Zezeze... how can a good idea of every new technology be discovered/invented by foreigners ?? Can't the Chinese think of it? Or something else ........
In the previous article, I introduced how to use dynamicproxy to implement predictionlog .. the core idea is to get the interface class of the actual object through reflection (in fact, the function description of the interface is obtained) and dynamically derive a class from the obtained interface class, all functions of this class (inherited from interfaces) are hooked. all function calls of this object are switched to invoke ....
Today I will introduce a relatively simple method... in fact, this Dongdong post in steeven uses attribute to implement AOP for C? The comment mentioned above: P
Let's take a step-by-step look at the code of this stuff: P
Public class interposer:
System. runtime. remoting. proxies. realproxy,
System. runtime. remoting. iremotingtypeinfo
Well, the above is the declaration of the class. It can be seen that this class is inherited from realproxy... Have you thought of anything? Is the actual class inherited from marshalbyrefobject ?? Also, what is iremotingtypeinfo ?? Haha, don't worry... let's look at the back...
Private interposer (object target)
:
Base (typeof (iinterposed ))
{
M_target = target;
}
It can be seen that the parameter passed to the base class is an iinterposed type ..
Public interface iinterposed
{
Object target
{
Get;
}
}
This is an interface. There is no method, and no attribute is implemented. Zeze is also a question mark ??. Don't worry, let's take a look at the following ..
Public override system. runtime. remoting. messaging. iMessage invoke (system. runtime. remoting. messaging. iMessage message)
{
System. runtime. remoting. messaging. imethodcallmessage methodmessage =
New system. runtime. remoting. messaging. methodcallmessagewrapper (system. runtime. remoting. messaging. imethodcallmessage) message );
System. reflection. methodbase method = methodmessage. methodbase;
Object returnvalue = NULL;
// Handle iinterposed methods/properties here. Right now, there is
// Only one property, so don't do any extensive checking to determine
// The method being invoked.
If (method. declaringtype = typeof (iinterposed ))
{
Returnvalue = m_target;
}
Else
{
Try {
Returnvalue = method. Invoke (m_target, methodmessage. ARGs );
}
Catch (system. Exception ex ){
Returnvalue = NULL;
}
}
System. runtime. remoting. messaging. returnmessage =
New system. runtime. remoting. messaging. returnmessage (returnvalue, methodmessage. ARGs, methodmessage. argcount, methodmessage. logicalcallcontext, methodmessage );
Return returnmessage;
}
Since it is implemented through transparent proxy, you have to have the invoke function, right, the above is the function.
Through the code above, we can find that the function of the m_target object is actually called, and m_target is the object passed in by the constructor...
This is where the transparent proxy is generated:
Public static object wrap (object target)
{
Interposer = new interposer (target );
Return interposer. gettransparentproxy ();
}
Well, most of them should be clear here. Pass in the actual object (which you want to operate) through the constructor to get the transparent proxy, and then call it through the transparent proxy ..
Wait. The parameter passed to the realproxy class is iinterposed, not our actual object ????
Well, this is the key ". this class inherits from iremotingtypeinfo. After this interface is implemented, we can convert this type to any type (theoretically, it can only be compiled during compilation. if you convert this class into a completely different class during the program running, it will generate an exception when calling the function ). when calling a function of the forcibly converted class, all the function call information of this object will be forwarded through the transparent proxy (even if he does not have this function, no exception will occur. If no transparent proxy is used, an exception will be generated as mentioned above.) Forward the exception to the invoke function. Here, we will call the actual function. in this case, we have completed the function call's big shift: p...
Okay, the core part is finished. Let's look at the client call method:
Public interface isampletarget
{
Void dosomething ();
Void doexception ();
}
Public interface inotimplemented
{
Void nothing ();
}
Public class sampletarget: isampletarget, inotimplemented
{
Public void dosomething ()
{
System. Console. writeline ("doing something .");
}
Public void doexception (Out int value)
{
Throw new system. Exception ("TT"); // test exception
}
}
Similarly, we have to inherit the class from the interface...
Sampletarget realtarget = new sampletarget ();
Isampletarget interposedtarget = (isampletarget) interposer. interposer. Wrap (realtarget );
Interposedtarget. dosomething ();
Object target = (interposer. iinterposed) interposedtarget). target;
System. Console. writeline ("interposed target type: {0}", target. GetType ());
Inotimplemented TARGET2 = (inotimplemented) interposedtarget;
Try
{
Target2.nothing ();
}
Catch (system. Exception E)
{
System. Console. writeline ("Expected exception: {0}", e );
}
The red part of the Code shows that the interposer object is converted to isampletarget (remember what I said before ?? ), And then call the function ....
Haha, the effect will be complete after you run it...
Download the source file from this location: interposer
The above method is lightweight and much simpler than the emit method... but like dynamicproxy, it still cannot interrupt constructor...
It seems that we may have to wait for the masterpiece of jgtm: P