zoukankan      html  css  js  c++  java
  • DispatchProxy实现动态代理及AOP

    DispatchProxy类是DotnetCore下的动态代理的类,源码地址:Github,官方文档:MSDN。主要是Activator以及AssemblyBuilder来实现的(请看源码分析),园子里的蒋老大提供的AOP框架Dora的实现也是大量使用了这两个,不过DispatchProxy的实现更简单点。

    AOP实现:

    #region 动态代理 dispatchproxy aop示例
    class GenericDecorator : DispatchProxy
    {
        public object Wrapped { get; set; }
        public Action<MethodInfo, object[]> Start { get; set; }
        public Action<MethodInfo, object[], object> End { get; set; }
    
        protected override object Invoke(MethodInfo targetMethod, object[] args)
        {
            Start(targetMethod, args);
            object result = targetMethod.Invoke(Wrapped, args);
            End(targetMethod, args, result);
            return result;
        }
    }
    
    interface IEcho
    {
        void Echo(string message);
        string Method(string info);
    }
    
    class EchoImpl : IEcho
    {
        public void Echo(string message) => Console.WriteLine($"Echo参数:{message}");
    
        public string Method(string info)
        {
            Console.WriteLine($"Method参数:{info}");
            return info;
        }
    }
    #endregion
    

    调用:

    static void EchoProxy()
    {
        var toWrap = new EchoImpl();
        var decorator = DispatchProxy.Create<IEcho, GenericDecorator>();
        ((GenericDecorator)decorator).Wrapped = toWrap;
        ((GenericDecorator)decorator).Start = (tm, a) => Console.WriteLine($"{tm.Name}({string.Join(',', a)})方法开始调用");
        ((GenericDecorator)decorator).End = (tm, a, r) => Console.WriteLine($"{tm.Name}({string.Join(',', a)})方法结束调用,返回结果{r}");
        decorator.Echo("Echo");
        decorator.Method("Method");
    }
    

    DispatchProxy是一个抽象类,我们自定义一个派生自该类的类,通过Create方法建立代理类与代理接口的依赖即可。结果:

    首先,我们要有三个概念:代理接口、委托类、代理类;分别对应着上面示例代码里面的IEcho、EchoImpl、GenericDecorator。我们动态的创建一个派生自代理接口的代理类,同时封装委托类的实例,那么我们调用代理类的方法实质上就是在调用内部的委托类的方法,因此我们只需要在代理类的特定方法前后注入逻辑即可完成AOP操作。 这个思路也是上面提到的Dora框架中拦截器的思路。也是绝大数AOP框架实现的基本思路。
  • 相关阅读:
    linux内存的使用与page buffer (转)
    基于linux2.6.38.8内核的SDIO/wifi驱动分析(转)
    RamDisk块设备驱动实例开发讲解一
    Linux加密框架设计与实现(转)
    v4l2子系统学习心得
    一句memset引发的疑案
    linux 信号量之SIGNAL 0(转)
    可重入函数
    从ARM VIVT看linux的cache 处理
    内核抢占与preempt_count
  • 原文地址:https://www.cnblogs.com/zhiyong-ITNote/p/11058595.html
Copyright © 2011-2022 走看看