Aspectsharp Example Analysis

Source: Internet
Author: User

The example provided by aspectsharp provides a simple logger interceptor and a persistent mixer. Let's take a look at its working principles.

1. Class and Interface Description:

IMessage: Message object interface. (must the interface be declared for the object implementing aspect ?)
Messageimpl: implements the iMessage interface;
Imessagepersistence: Message Object Persistence interface;
Loggerinterceptor: log interceptor;
Messagepersistencemixin: Message persistent mixer, which implements the imessagepersistence interface;

2. Main program code:

// Creating the proxy
IMessage message = aspectsharpengine. Wrap (New messageimpl () as iMessage;

Message. Message = "test";
// Note 1: Obviously this message is not an object that actually implements iMessage; otherwise, the method cannot be intercepted.

// Casting to the persistence service
Imessagepersistence Persistence = (imessagepersistence) message;
// NOTE 2: The message object does not implement the imessagepersistence interface!

Persistence. Save ();

I can't imagine how AOP works when I see this code. It's a bit of a time-out;
The key lies in this proxy object. First, make the following assumption:

Message. Message = "test";
This message is definitely not an instance of messageimpl. What is this message? It may be an aspect object (the aspect object contains all the interceptor and mixer of the object). It encapsulates the messageimpl object. What cannot be explained is that aspect does not inherit from the iMessage interface?

Imessagepersistence Persistence = (imessagepersistence) message;
This is easy to understand. Although the message does not implement imessagepersistence, you only need to reload the as operation to get what we want.

3. aspectsharpengine

You can see the name. The core object of aspectsharp is responsible for encapsulating the object. Let's take a look at the code of the encapsulated object:

Public static object wrap (object target)
{
Type origintype = target. GetType ();
String typename = origintype. fullname;

// Get the invocation processing object. The default value is defaultinvocationhandler.
Iinvocationhandler handler = getinvocationhandler (target );

// Obtain the processing object of mixininvocation. The default value is mixininvocationhandler.
Imixininvocationhandler mixinhandler = getmixininvocationhandler ();

// Obtain all the mixers added to the object. The mixer is declared in the configuration file.
Imixin [] mixins = getmixins (typename );

// Check the cache
If (! _ Typecache. Contains (typename ))
{
// Obtain the object implementation Interface
Type [] interfaces = getinterfacesfrom (origintype );

// Obtain the object type of the proxy. Note that the interface implemented by the object and all mixer interfaces are passed in,
// Will an object type be created to implement all these interfaces?
Type proxytype = proxygenerator. createproxytype (interfaces, mixins );

_ Typecache. Add (typename, proxytype );
}

// Return the instance of the encapsulated object.
Return proxygenerator. createinstance (
_ Typecache [typename], mixins, handler, mixinhandler );
}

4. proxygenerator

Creates proxy object types and instances.

/// Generates a proxy transient type implementing all the specified interfaces and mixins
/// Redirecting method invocations to the specifed handler.
The above section describes the createproxytype method. As I think, you must create a proxy object that implements all interfaces. Year! I admire myself a bit. (If you have something, just throw it .)

Internal static type createproxytype (type [] interfaces, imixin [] mixins)
{
//...
// Create an assembly
Assemblyname = new assemblyname ();
Assemblyname. Name = "dynamicassemblyproxygen ";

// Define a dynamic assembly
Assemblybuilder =
Appdomain. currentdomain. definedynamicassembly (
Assemblyname,
Assemblybuilderaccess. Run );

Modulebuilder =
Assemblybuilder. definedynamicmodule (assemblyname. Name, true );

Typebuilder = modulebuilder. definetype (
"Proxytype", typeattributes. Public | typeattributes. Class, null, mergetypes (interfaces, mixins ));

Fieldbuilder handlerfield = generatefield (typebuilder, handlerfieldname, typeof (iinvocationhandler ));

Fieldbuilder mixinhandlerfield = generatefield (typebuilder, mixinhandlerfieldname, typeof (imixininvocationhandler ));

Fieldbuilder mixinsfield = generatefield (typebuilder, "mixins", typeof (imixin []);

Constructorbuilder constr = generateconstructor (typebuilder, handlerfield, mixinsfield, mixinhandlerfield );

Generateinterfaceimplementation (typebuilder, interfaces, handlerfield); generatemixinimplementation

(Typebuilder, mixins, mixinhandlerfield, mixinsfield );

Return typebuilder. createtype ();
}
The header of the above Code is a little big. Please refer to. Net SDK,
As long as you know that this method creates an object type that implements all interfaces.

Public static object createinstance (type, imixin [] mixins,
Iinvocationhandler handler, imixininvocationhandler mixinhandler)
{
Return activator. createinstance (type, new object [] {handler, mixinhandler, mixins });
}
Directly create an instance. The object type is dynamically added to createproxytype. It is not aspect. An error is returned !.
It seems that the code for createproxytype should also be clarified. But I have a question: how can I add the dynamically created constructor to the code?

5. Configuration File

The configuration file content is relatively simple.
<Advices>
<Interceptors>
// Define the interceptor
<Interceptor type = "aspectsharp. sample. Interceptor. loggerinterceptor, aspectsharp. sample" name = "logger"/>
</Interceptors>
<Mixins>
// Define the mixer
<Mixin type = "aspectsharp. sample. Mixin. messagepersistencemixin, aspectsharp. sample" name = "persistence"/>
</Mixins>
</Advices>

<Aspects defaultnamespace = "aspectsharp. sample">
// Declare the object and mixer for aspect
<Aspect Mixin = "persistence" namespace = "model" typename = "messageimpl">
// The object to be intercepted,
<Pointcut interceptor = "logger" method = "set"/>
</Aspect>
</Aspects>

Obviously, the key of AOP lies in the proxy object that is dynamically established to implement all interfaces,
But how does this proxy object interact with our defined interceptor and mixer? Please pay attention to subsequent articles.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.