(精华)2020年8月13日 C#基础知识点 AOP实现原理(装饰器模式,代理模式,.Net Remoting真实代理,Castle动态代理,Unity动态代理)

(精华)2020年8月13日 C#基础知识点 AOP实现原理(装饰器模式,代理模式,.Net Remoting真实代理,Castle动态代理,Unity动态代理)

一:装饰器实现AOP

/// <summary>
/// 装饰器模式实现静态代理
/// AOP 在方法前后增加自定义的方法
/// </summary>
public class DecoratorAOP
{<!-- -->
    public static void Show()
    {<!-- -->
        User user = new User()
        {<!-- -->
            Name = "看看看看",
            Password = "123123123123"
        };
        IUserProcessor processor = new UserProcessor();
        processor.RegUser(user);
        Console.WriteLine("***************");

        processor = new UserProcessorDecorator(processor);
        processor.RegUser(user);
    }

    public interface IUserProcessor
    {<!-- -->
        void RegUser(User user);
    }
    public class UserProcessor : IUserProcessor
    {<!-- -->
        public void RegUser(User user)
        {<!-- -->
            Console.WriteLine("用户已注册。Name:{0},PassWord:{1}", user.Name, user.Password);
        }
    }
    /// <summary>
    /// 装饰器的模式去提供一个AOP功能
    /// </summary>
    public class UserProcessorDecorator : IUserProcessor
    {<!-- -->
        private IUserProcessor _UserProcessor {<!-- --> get; set; }
        public UserProcessorDecorator(IUserProcessor userprocessor)
        {<!-- -->
            this._UserProcessor = userprocessor;
        }

        public void RegUser(User user)
        {<!-- -->
            BeforeProceed(user);

            this._UserProcessor.RegUser(user);

            AfterProceed(user);
        }

        /// <summary>
        /// 业务逻辑之前
        /// </summary>
        /// <param name="user"></param>
        private void BeforeProceed(User user)
        {<!-- -->
            Console.WriteLine("方法执行前");
        }
        /// <summary>
        /// 业务逻辑之后
        /// </summary>
        /// <param name="user"></param>
        private void AfterProceed(User user)
        {<!-- -->
            Console.WriteLine("方法执行后");
        }
    }
}

二:代理模式实现AOP

 /// <summary>
    /// 代理模式实现静态代理
    /// AOP 在方法前后增加自定义的方法
    /// </summary>
    public class ProxyAOP
    {<!-- -->
        public static void Show()
        {<!-- -->
            User user = new User()
            {<!-- -->
                Name = "哈哈哈哈",
                Password = "123123123123"
            };
            IUserProcessor processor = new UserProcessor();
            processor.RegUser(user);
            Console.WriteLine("***************");

            processor = new ProxyUserProcessor();
            processor.RegUser(user);
        }

        public interface IUserProcessor
        {<!-- -->
            void RegUser(User user);
        }
        public class UserProcessor : IUserProcessor
        {<!-- -->
            public void RegUser(User user)
            {<!-- -->
                Console.WriteLine("用户已注册。Name:{0},PassWord:{1}", user.Name, user.Password);
            }
        }

        /// <summary>
        /// 代理模式去提供一个AOP功能
        /// </summary>
        public class ProxyUserProcessor : IUserProcessor
        {<!-- -->
            private IUserProcessor _UserProcessor = new UserProcessor();
            public void RegUser(User user)
            {<!-- -->
                BeforeProceed(user);
                this._UserProcessor.RegUser(user);
                AfterProceed(user);
            }

            /// <summary>
            /// 业务逻辑之前
            /// </summary>
            /// <param name="user"></param>
            private void BeforeProceed(User user)
            {<!-- -->
                Console.WriteLine("方法执行前");
            }
            /// <summary>
            /// 业务逻辑之后
            /// </summary>
            /// <param name="user"></param>
            private void AfterProceed(User user)
            {<!-- -->
                Console.WriteLine("方法执行后");
            }
        }

    }

三:使用.Net Remoting/RealProxy 真实代理实现AOP

/// <summary>
    /// 使用.Net Remoting/RealProxy 实现动态代理
    /// 局限在业务类必须是继承自MarshalByRefObject类型
    /// </summary>
    public class RealProxyAOP
    {<!-- -->
        public static void Show()
        {<!-- -->
            User user = new User()
            {<!-- -->
                Name = "换换换",
                Password = "123456"
            };

            UserProcessor processor = new UserProcessor();
            processor.RegUser(user);

            Console.WriteLine("*********************");
            UserProcessor userProcessor = TransparentProxy.Create<UserProcessor>();
            userProcessor.RegUser(user);
        }

        /// <summary>
        /// 真实代理
        /// </summary>
        /// <typeparam name="T"></typeparam>
        public class MyRealProxy<T> : RealProxy
        {<!-- -->
            private T tTarget;
            public MyRealProxy(T target)
                : base(typeof(T))
            {<!-- -->
                this.tTarget = target;
            }

            public override IMessage Invoke(IMessage msg)
            {<!-- -->
                BeforeProceede(msg);//Log  try-catch

                IMethodCallMessage callMessage = (IMethodCallMessage)msg;
                object returnValue = callMessage.MethodBase.Invoke(this.tTarget, callMessage.Args);

                AfterProceede(msg);

                return new ReturnMessage(returnValue, new object[0], 0, null, callMessage);
            }
            public void BeforeProceede(IMessage msg)
            {<!-- -->
                Console.WriteLine("方法执行前可以加入的逻辑");
            }
            public void AfterProceede(IMessage msg)
            {<!-- -->
                Console.WriteLine("方法执行后可以加入的逻辑");
            }
        }

        /// <summary>
        /// 透明代理
        /// </summary>
        public static class TransparentProxy
        {<!-- -->
            public static T Create<T>()
            {<!-- -->
                T instance = Activator.CreateInstance<T>();
                MyRealProxy<T> realProxy = new MyRealProxy<T>(instance);
                T transparentProxy = (T)realProxy.GetTransparentProxy();
                return transparentProxy;
            }
        }


        public interface IUserProcessor
        {<!-- -->
            void RegUser(User user);
        }

        /// <summary>
        /// 必须继承自MarshalByRefObject父类,否则无法生成
        /// </summary>
        public class UserProcessor : MarshalByRefObject, IUserProcessor
        {<!-- -->
            public void RegUser(User user)
            {<!-- -->
                Console.WriteLine("用户已注册。用户名称{0} Password{1}", user.Name, user.Password);
            }
        }

    }

四:使用Castle\DynamicProxy 动态代理实现AOP

/// <summary>
    /// 使用Castle\DynamicProxy 实现动态代理
    /// 方法必须是虚方法
    /// </summary>
    public class CastleProxyAOP
    {<!-- -->
        public static void Show()
        {<!-- -->
            User user = new User()
            {<!-- -->
                Name = "啦啦啦",
                Password = "123456"
            };
            ProxyGenerator generator = new ProxyGenerator();
            MyInterceptor interceptor = new MyInterceptor();
            UserProcessor userprocessor = generator.CreateClassProxy<UserProcessor>(interceptor);
            userprocessor.RegUser(user);
        }
        public interface IUserProcessor
        {<!-- -->
            void RegUser(User user);
        }

        public class UserProcessor : IUserProcessor
        {<!-- -->
            /// <summary>
            /// 必须带上virtual 否则无效~
            /// </summary>
            /// <param name="user"></param>
            public virtual void RegUser(User user) 
            {<!-- -->
                Console.WriteLine($"用户已注册。Name:{user.Name},PassWord:{user.Password}");
            }
        }

        public class MyInterceptor : IInterceptor
        {<!-- -->
            public void Intercept(IInvocation invocation)
            {<!-- -->
                PreProceed(invocation);
                invocation.Proceed();//就是调用原始业务方法
                PostProceed(invocation);
            }
            public void PreProceed(IInvocation invocation)
            {<!-- -->
                Console.WriteLine("方法执行前");
            }

            public void PostProceed(IInvocation invocation)
            {<!-- -->
                Console.WriteLine("方法执行后");
            }
        }
    }

五:使用EntLib\PIAB Unity 实现动态代理

public class UnityAOP
    {<!-- -->
        public static void Show()
        {<!-- -->
            User user = new User()
            {<!-- -->
                Name = "Unity",
                Password = "1234567890123456789"
            };
            //-----------------------声明一个容器------------------------
            IUnityContainer container = new UnityContainer();
            //container.RegisterType<IUserProcessor, UserProcessor>();//声明UnityContainer并注册IUserProcessor
            //IUserProcessor processor = container.Resolve<IUserProcessor>();
            //processor.RegUser(user);
            //-----------------------添加并配置拦截器------------------------
            container.AddNewExtension<Interception>();
            container.RegisterType<IUserProcessor, UserProcessor>()
            .Configure<Interception>()
                .SetInterceptorFor<IUserProcessor>(new InterfaceInterceptor());


            //映射类型
            IUserProcessor userprocessor = container.Resolve<IUserProcessor>();

            Console.WriteLine("********************");
            userprocessor.RegUser(user);//调用
            userprocessor.GetUser(user);//调用
        }

        #region 特性对应的行为
        public class UserHandler : ICallHandler
        {<!-- -->
            public int Order {<!-- --> get; set; }
            public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
            {<!-- -->
                User user = input.Inputs[0] as User;
                if (user.Password.Length < 10)
                {<!-- -->
                    return input.CreateExceptionMethodReturn(new Exception("密码长度不能小于10位"));
                }
                Console.WriteLine("参数检测无误");

                IMethodReturn methodReturn = getNext()(input, getNext);
                return methodReturn;
            }
        }

        public class LogHandler : ICallHandler
        {<!-- -->
            public int Order {<!-- --> get; set; }

            public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
            {<!-- -->
                User user = input.Inputs[0] as User;
                string message = $"RegUser:Username:{user.Name},Password:{user.Password}";
                Console.WriteLine("日志已记录,Message:{0},Ctime:{1}", message, DateTime.Now);
                return getNext()(input, getNext);
            }
        }


        public class ExceptionHandler : ICallHandler
        {<!-- -->
            public int Order {<!-- --> get; set; }
            public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
            {<!-- -->
                IMethodReturn methodReturn = getNext()(input, getNext);
                if (methodReturn.Exception == null)
                {<!-- -->
                    Console.WriteLine("无异常");
                }
                else
                {<!-- -->
                    Console.WriteLine($"异常:{methodReturn.Exception.Message}");
                }
                return methodReturn;
            }
        }

        public class AfterLogHandler : ICallHandler
        {<!-- -->
            public int Order {<!-- --> get; set; }
            public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
            {<!-- -->
                IMethodReturn methodReturn = getNext()(input, getNext);
                User user = input.Inputs[0] as User;
                string message = string.Format("RegUser:Username:{0},Password:{1}", user.Name, user.Password);
                Console.WriteLine("完成日志,Message:{0},Ctime:{1},计算结果{2}", message, DateTime.Now, methodReturn.ReturnValue);
                return methodReturn;
            }
        }
        #endregion 特性对应的行为

        #region 特性
        public class UserHandlerAttribute : HandlerAttribute
        {<!-- -->
            public override ICallHandler CreateHandler(IUnityContainer container)
            {<!-- -->
                ICallHandler handler = new UserHandler() {<!-- --> Order = this.Order };
                return handler;
            }
        }

        public class LogHandlerAttribute : HandlerAttribute
        {<!-- -->
            public override ICallHandler CreateHandler(IUnityContainer container)
            {<!-- -->
                return new LogHandler() {<!-- --> Order = this.Order };
            }
        }

        public class ExceptionHandlerAttribute : HandlerAttribute
        {<!-- -->
            public override ICallHandler CreateHandler(IUnityContainer container)
            {<!-- -->
                return new ExceptionHandler() {<!-- --> Order = this.Order };
            }
        }

        public class AfterLogHandlerAttribute : HandlerAttribute
        {<!-- -->
            public override ICallHandler CreateHandler(IUnityContainer container)
            {<!-- -->
                return new AfterLogHandler() {<!-- --> Order = this.Order };
            }
        }
        #endregion 特性

        #region 业务
        [UserHandlerAttribute(Order = 1)]
        [ExceptionHandlerAttribute(Order = 3)]
        [LogHandlerAttribute(Order = 2)]
        [AfterLogHandlerAttribute(Order = 5)]
        public interface IUserProcessor
        {<!-- -->
            void RegUser(User user);
            User GetUser(User user);
        }

        public class UserProcessor : IUserProcessor
        {<!-- -->
            public void RegUser(User user)
            {<!-- -->
                Console.WriteLine("用户已注册。");
            }

            public User GetUser(User user)
            {<!-- -->
                return user;
            }
        }
        #endregion 业务
    }

五:使用EntLib\PIAB Unity 读取配置文件方式实现动态代理

第一步:使用Unity需要nuget引入6个包

  1. Unity1. Unity.Abstractions1. Unity.Configuration1. Unity.Container1. Unity.Interception1. Unity.Interception.Configuration 第二步:固定写法
public class UnityConfigAOP
    {<!-- -->
        public static void Show()
        {<!-- -->
            User user = new User()
            {<!-- -->
                Name = "配置文件方式实现",
                Password = "1234567890123456789"
            };
            //创建容器
            IUnityContainer container = new UnityContainer();
            //扩展配置文件映射
            ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
            fileMap.ExeConfigFilename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "CfgFiles\\Unity.Config");
            //指向扩展配置文件
            Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
            //容器注入到UnityConfigurationSection中
            UnityConfigurationSection configSection = (UnityConfigurationSection)configuration.GetSection(UnityConfigurationSection.SectionName);
            configSection.Configure(container, "aopContainer");
            //使用
            IUserProcessor processor = container.Resolve<IUserProcessor>();
            processor.RegUser(user);
            processor.GetUser(user);
        }
    }

三:配置文件

<configuration>
  <configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Unity.Configuration"/>
    <!--Microsoft.Practices.Unity.Configuration.UnityConfigurationSection-->
  </configSections>
  <unity>
    <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Unity.Interception.Configuration"/>
    <containers>
      <container name="aopContainer">
        <extension type="Interception"/>  
        <register type="MyAOP.UnityWay.IUserProcessor,MyAOP" mapTo="MyAOP.UnityWay.UserProcessor,MyAOP">
          <interceptor type="InterfaceInterceptor"/> 
          <interceptionBehavior type="MyAOP.UnityWay.MoniterBehavior, MyAOP"/>
          <interceptionBehavior type="MyAOP.UnityWay.LogBeforeBehavior, MyAOP"/>
          <interceptionBehavior type="MyAOP.UnityWay.ParameterCheckBehavior, MyAOP"/>
          <interceptionBehavior type="MyAOP.UnityWay.CachingBehavior, MyAOP"/>
          <interceptionBehavior type="MyAOP.UnityWay.ExceptionLoggingBehavior, MyAOP"/>
          <interceptionBehavior type="MyAOP.UnityWay.LogAfterBehavior, MyAOP"/> 
        </register>
      </container>
    </containers>
  </unity>
</configuration>

四:aop切面拦截器的类

/// <summary>
    /// 不需要特性
    /// </summary>
    public class MoniterBehavior : IInterceptionBehavior
    {<!-- -->
        public IEnumerable<Type> GetRequiredInterfaces()
        {<!-- -->
            return Type.EmptyTypes;
        }

        public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
        {<!-- -->
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start(); 
            // 可以在这儿添加方法之前的逻辑

            var query = getNext().Invoke(input, getNext);


            stopwatch.Stop();
            Console.WriteLine($"执行耗时:{stopwatch.ElapsedMilliseconds} ms"); 
            return query; 
        }

        public bool WillExecute
        {<!-- -->
            get {<!-- --> return true; }
        }
    }
public class LogBeforeBehavior : IInterceptionBehavior
    {<!-- -->
        public IEnumerable<Type> GetRequiredInterfaces()
        {<!-- -->
            return Type.EmptyTypes;
        }

        public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
        {<!-- -->
            Console.WriteLine("LogBeforeBehavior");
            foreach (var item in input.Inputs)
            {<!-- -->
                Console.WriteLine(item.ToString());//反射获取更多信息
            }
            var query = getNext().Invoke(input, getNext);

            //下一个节点的方法已经执行完毕   
            //在这里计入方法执行后的逻辑
            return query;

            //现在是21:53 大家开始提问 && 休息  21:57 开始答疑!期间老师不说话
        }

        public bool WillExecute
        {<!-- -->
            get {<!-- --> return true; }
        }
    }
public class ParameterCheckBehavior : IInterceptionBehavior
    {<!-- -->
        public IEnumerable<Type> GetRequiredInterfaces()
        {<!-- -->
            return Type.EmptyTypes;
        }

        public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
        {<!-- -->
            Console.WriteLine("ParameterCheckBehavior");
            //通过特性校验
            User user = input.Inputs[0] as User;
            if (user.Password.Length < 10)
            {<!-- -->
                //throw new Exception(); 
                return input.CreateExceptionMethodReturn(new Exception("密码长度不能小于10位"));
            }
            else
            {<!-- -->
                Console.WriteLine("参数检测无误");
                return getNext().Invoke(input, getNext);
            }
        }

        public bool WillExecute
        {<!-- -->
            get {<!-- --> return true; }
        }
    }
public class CachingBehavior : IInterceptionBehavior
    {<!-- -->
        public IEnumerable<Type> GetRequiredInterfaces()
        {<!-- -->
            return Type.EmptyTypes;
        }

        public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
        {<!-- -->
            Console.WriteLine("CachingBehavior");
            //input.Target.GetType().GetCustomAttributes()
            if (input.MethodBase.Name.Equals("GetUser"))
                return input.CreateMethodReturn(new User() {<!-- --> Id = 234, Name = "Richard" });
            return getNext().Invoke(input, getNext);
        }

        public bool WillExecute
        {<!-- -->
            get {<!-- --> return true; }
        }
    }
public class ExceptionLoggingBehavior : IInterceptionBehavior
    {<!-- -->
        public IEnumerable<Type> GetRequiredInterfaces()
        {<!-- -->
            return Type.EmptyTypes;
        }

        public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
        {<!-- -->
            Console.WriteLine("ExceptionLoggingBehavior");
            IMethodReturn methodReturn = getNext()(input, getNext);
            if (methodReturn.Exception == null)
            {<!-- -->
                Console.WriteLine("无异常");
            }
            else
            {<!-- -->
                Console.WriteLine($"异常:{methodReturn.Exception.Message}");
            }
            return methodReturn;
        }

        public bool WillExecute
        {<!-- -->
            get {<!-- --> return true; }
        }
    }
public class LogAfterBehavior : IInterceptionBehavior
    {<!-- -->
        public IEnumerable<Type> GetRequiredInterfaces()
        {<!-- -->
            return Type.EmptyTypes;
        }


        //一切正常的  刷个1
        public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
        {<!-- -->
            Console.WriteLine("LogAfterBehavior");
            foreach (var item in input.Inputs)
            {<!-- -->
                Console.WriteLine(item.ToString());//反射获取更多信息
            }
            IMethodReturn methodReturn = getNext()(input, getNext);
            Console.WriteLine("LogAfterBehavior" + methodReturn.ReturnValue);
            return methodReturn;
        }

        public bool WillExecute
        {<!-- -->
            get {<!-- --> return true; }
        }
    }
posted @ 2020-12-30 12:04  不要摸我的腰  阅读(241)  评论(0编辑  收藏  举报