Dynamic Proxy: Dynamic proxy

Source: Internet
Author: User

Reproduced http://www.zeroport.net

SummaryArticleThis article describes how Castle's dynamic proxy implements AOP.

I have always been "tailism", that is, just use it, no matter how it is implemented. Recently, I have been paying close attention to AOP, Io C, and other technologies because I want to add them to the project. Later, dynamicproxy in the castleproject was selected as the object of interest. However, I was greedy this time and didn't want to know how to implement it. So I began to look into how Castle implemented AOP.

Proxy is one of the ways to implement AOP. It can effectively intercept the execution process of a class method through proxy.

From the test example in Castle, we can see that Castle uses dynamicCodeGenerate a proxy for the class to be intercepted to achieve the goal of weaving. But how is Castle woven? I plan to use a simple example to test the dynamic code generated by Castle.

Scene I imagine an example. A class has a method: dosomething, which outputs Yes, * is running dosomething, where * indicates the name of the class. Then I need to output now I'm starting do something and now I'm ending dosomething before and after this class calls dosomething. Of course, there are many ways to achieve this. As Castle uses proxy, I only use proxy here.

For the traditional proxy mode, the following class diagram can be obtained:

Figure 1

The class code is as follows:

Figure 2: code for Class

Figure 3: realanovirtual code

Figure 4: proxyclass code

Then, you can write the code as follows:

Figure 5: run the code

Run the above Code to produce the following results:

Figure 6: running result

The dosomething method can be used transparently through proxy.

Obviously, castle also needs to generate such a proxy class so that it can call the user-specified code before calling dosomething. Therefore, Castle provides dynamicproxy and interceptor to achieve the goal. Dynamicproxy generates a proxy class that acts as a proxy for dosomething operations. When acting as a proxy for dosomething operations, the user-specified interceptor is used to intercept operations.

To see what the dynamic proxy generated by Castle is like, I wrote a class: reala. The Code is as follows:

Figure 7: reala code

There is only one method in reala, dosomething. I need to achieve the same effect as the previous traditional mode before and after the dosomething operation. According to Castle's requirements, I need to write an interceptor to block the operations before and after. The Code is as follows:

Figure 8: Interceptor code

Let's continue without thinking about how proxyinterceptor is.

With the interceptor and class to be intercepted, you can directly use the following code:

Figure 9: run the code

Figure 10: running result

Bingle !!!, Succeeded.

So what exactly does Castle do?

During running, Castle generates an assembly and stores it in the application running directory named generatedassembly. dll. By decompiling this assembly, you can see exactly what Castle has done.

For better description, I describe the decompiled code in segments:

1. Castle generates a proxy class cproxytypereala0, which inherits from reala:

Public Class C proxy type real A0: real

{

...

}

2. Some fields are defined in the cproxytypereala0 class:

Figure 11: Field Definition

The delegate is defined as follows:

Figure 12: Delegate Definition

So what are the purposes of these delegate? The code in the cproxytypereala0 constructor shows the purpose:

Figure 13: Constructor

Here, we are concerned with dosomething. From the preceding constructor code, we can see that delegate points to the callback _ dosomething callback function. The code of this function is as follows:

Figure 14: callback function code

In this callback function, the dosomething method of reala is called directly.

So how does Castle call the dosomething method of reala?

3. Call chain

In cproxytypereala0, The dosomething method of reala is overwritten, as follows:

Figure 15: overwrite dosomething

From the code, we can see that dosomething calls the local method _ method2invocation to obtain an invocation, and then calls Interceptor to execute some actions.

Take a closer look, a parameter This is input when _ method2invocation is called.Cached1. This parameter is a delegate object and points to the callback function callback_dosomething In the constructor. This is critical, so we need to look at what _ method2invocation has done.

Figure 16 method2invocation code

In the method2invocation method, an invocation corresponding to methodinfo is created/obtained, while invocation encapsulates the passed-In delegate and other related information.

Obviously, this information is encapsulated for better transmission. From method2invocation, the next step is to call the interceptor passed in the constructor.

Interceptor's intercept method requires two parameters: one is the previously encapsulated invocation object, and the other is a parameter array. Currently, it cannot be seen that this parameter array is useful.

So what does the intercept method do?

Let's look at the implementation code of interceptor. In my example, interceptor directly inherits from standardinterceptor, so let's first look at the code of standardinterceptor:

Figure 17 standardinterceptor code

It can be seen from the code that this is a template mode. The preprocess and postprocess methods are called respectively. In this way, we can call the two methods that I overwrite. However, the dosomething method is still not called here. Don't worry. The Code calls the process method of the passed-In invocaion object. So what does this method do?

Because the sameclassinvocation object is created in method2invocation, you can directly view the sameclassinvocation code:

Figure 18 sameclassinvocation code

Bingle !!! The process method calls the passed delegate object, so that the callback function callback_dosomething is called, and the callback function calls the dosomething method of reala. In this way, a complete interception process is implemented. At the same time, we can see that the preceding parameter array is dosomething's

Parameter array, but there is no parameter in the example, so it is zero.

So far, we have seen the whole process of Castle's code weaving:

First, a proxy class is generated by code, which inherits the class to be woven. Then, override the method to be intercepted in the proxy class, encapsulate the invocation object in the covered method, and pass the intercept method of the intercepter object passed in to the user. The intercept method calls the preprocess of intercepter in sequence, and calls the callback function directed to by the delegate passed in through invocation. The postprocess method of intercepter is used to intercepter.

The example is compiled and run in snippet comiler 2.0. You must add reference to Castle. dynamicproxy. dll during compilation.

If you are running in vs. net, you need to create your own project and add the files in the compressed package.

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.