Implementing simple AOP with the. NET Core Class Library System.Reflection.DispatchProxy

Source: Internet
Author: User
Tags aop reflection
Background

AOP is the aspect-oriented programming, Castle is the most well-known in many AOP frameworks, and there are dead spring.net, of course, the. NET Core Community rookie Aspectcore is excellent in performance and functionality, has gradually been respected by the community and more and more people use. Thanks for the gift of lemon classmate!

If you want to implement an AOP because of your own needs or learning, do you think that you should use emit to do it? Recently I learned that System.Reflection.DispatchProxy this Corefx class library, has implemented the dynamic agent function.

System.Reflection.DispatchProxy

Here's how it's used:

class Program{    static void Main(string[] args)    {        //创建代理类,并把SamepleProxy作为拦截器注入        var samepleProxy = (targetInterface)SamepleProxy.Create<targetInterface, SamepleProxy>();        //执行接口方法        samepleProxy.Write("here is invoke by proxy");    }}//需要被生成代理实例的接口public interface targetInterface{    //这个方法会被代理类实现    void Write(string writesomeshing);}public class SamepleProxy : DispatchProxy{    /// <summary>    /// 拦截调用    /// </summary>    /// <param name="method">所拦截的方法信息</param>    /// <param name="parameters">所拦截方法被传入的参数指</param>    /// <returns></returns>    protected override object Invoke(MethodInfo targetMethod, object[] args)    {        Console.WriteLine(args[0]);        return null;    }}
To create a simple AOP why?

System.Reflection.DispatchProxyThere is only one API, that is objecct Create<T,TProxy>() where TProxy:DispatchProxy , constraining the passing of only generic parameters, and cannot pass in the type from the method, which poses many problems. And more exasperating is, to the official issue, or not to add this API ...

Transformation method

Fortunately, under that issue, the issue author provides a solution to construct this generic method with reflection. I am also on this basis, encapsulated a bit, added the incoming interceptor instance and incoming interceptor construction method parameters of the function.

/// <summary>/// 拦截器接口/// </summary>public interface IInterceptor{    /// <summary>    /// 拦截器调用    /// </summary>    /// <param name="target">代理实例</param>    /// <param name="method">所拦截的方法</param>    /// <param name="parameters">所拦截方法传入的参数值</param>    /// <returns>返回值会传递给方法返回值</returns>        object Intercept(object target, MethodInfo method, object[] parameters);}

To implement this interface, the following is the encapsulation of the Dispatchproxy, implementing more methods for creating proxy instances

public class proxygenerator:dispatchproxy{Private Iinterceptor interceptor {get; set;}    <summary>///Create a proxy instance///</summary>//<param name= "TargetType" > The type of interface to be proxied </param> <param name= "Interceptor" > Interceptor </param>//<returns> Proxy instance </returns> public static object        Create (Type TargetType, Iinterceptor Interceptor) {Object proxy = GetProxy (TargetType); ((proxygenerator) proxy).        CreateInstance (Interceptor);    return proxy; }///<summary>//Create a proxy instance///</summary>//<param name= "TargetType" > The interface type to be proxied &LT;/PARAM&G    T <param name= "Interceptortype" > Interceptor type </param>//<param name= "Parameters" > Interceptor constructor parameter Value </param >///<returns> Proxy instance </returns> public static object Create (type TargetType, type Interceptortype, para        Ms Object[] Parameters) {Object proxy = GetProxy (TargetType); ((proxygenerator) proxy). CreAteinstance (interceptortype, parameters);    return proxy; }///<summary>//Create proxy instance Ttarget: The type of interface to be proxied tinterceptor: Interceptor Type///</summary>//<param name= "Parameters" > Interceptor constructor parameter Values </param>//<returns> Proxy instance </returns> public static Ttarget Create<tta Rget, tinterceptor> (params object[] parameters) where Tinterceptor:iinterceptor {var proxy = GetProxy (type        Of (Ttarget)); ((proxygenerator) proxy).        CreateInstance (typeof (Tinterceptor), parameters);    Return (ttarget) proxy; } private static Object GetProxy (Type targetType) {var callexp = Expression.call (typeof (Dispatchproxy), name        Of (Dispatchproxy.create), new[] {targetType, typeof (Proxygenerator)}); Return expression.lambda<func<object>> (CALLEXP).    Compile () (); } private void CreateInstance (Type interceptortype, object[] parameters) {var ctorparams = parameters. Select (x = X.gettype ()).        ToArray ();var paramsexp = parameters.        Select (x = expression.constant (x));        var newexp = expression.new (Interceptortype.getconstructor (ctorparams), paramsexp); This.interceptor = expression.lambda<func<iinterceptor>> (newexp).    Compile () ();    } private void CreateInstance (Iinterceptor interceptor) {this.interceptor = interceptor; } protected Override Object Invoke (MethodInfo method, object[] parameters) {return this.interceptor.Intercep    T (method, parameters); }}
How to use
    Class Program {static void Main (string[] args) {var poxy1 = (targetinterface) Proxygenera Tor.            Create (typeof (Targetinterface), New Samepleproxy ("Coreproxy1")); Poxy1. Write ("Here is invoked"); ---> "Here is invoked by Coreproxy1" var poxy2 = (targetinterface) proxygenerator.create (typeof (Targetinte            Rface), typeof (Samepleproxy), "Coreproxy2"); Poxy2. Write ("Here is invoked"); ---> "Here is invoked by Coreproxy2" var poxy3 = Proxygenerator.create<targetinterface, SAMEPLEPROXY&G            t; ("Coreproxy3"); Poxy3. Write ("Here is invoked"); ---> ' Here is invoked by Coreproxy3 '}} public class Samepleproxy:iinterceptor {private S        Tring proxyname {get;}        Public Samepleproxy (string name) {this.proxyname = name; } public Object Intercept (MethodInfo method, object[] parameters) {Console.WriteLine (parameters[ 0] + "by" + Proxyname);        return null;    }} public interface Targetinterface {void Write (string writesome); }
Summarize

To sum up, Microsoft's father gave us this wheel is still light and very useful.
The example code for this article can be found on my github:

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.