zoukankan      html  css  js  c++  java
  • .NET知识梳理——8.AOP

    1. AOP

    AOP:允许开发者动态的修改静态的OO模型,就像现实生活中对象在生命周期中会不断的改变自身。   

    AOP是一种编程思想,是OOP思想的补充

    1.1        AOP面向切面编程

    1.1.1  AOP有以下好处

    1.1.1.1      聚焦核心业务逻辑

    权限/异常/日志/缓存/事务等通用功能可以通过AOP方式添加,程序设计简单,

    1.1.1.2      功能动态扩展

    集中管理,代码复用;规范化;

    1.1.2  实现AOP的多种方式

    l  静态实现--装饰器/代理模式

    l  动态实现--Remoting/Castle(Emit)

    l  静态织入--PostSharp(收费)--扩展编译工具,生成的加入额外代码

    l  依赖注入容器的AOP扩展(开发)

    l  MVC的Filter--特性标记,然后该方法执行前/后就多了逻辑

    invoker调用中心--负责反射调用方法--检查特性--有则执行额外逻辑

    1.2        静态AOP实现

    静态AOP 可以通过装饰器模式或代理模式进行编码实现。

    1.2.1  装饰器模式实现

    /// <summary>

        /// 装饰器模式实现静态代理

        /// </summary>

        public class DecoratorAOP

        {

            public static void Show()

            {

                User user = new User()

                {

                    Name = "Olive",

                    Password = "116"

                };

                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:{user.Name},Password:{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);

                }

     

                private void BeforeProceed(User user)

                {

                    Console.WriteLine("方法执行前");

                }

                private void AfterProceed(User user)

                {

                    Console.WriteLine("方法执行后");

                }

            }

    }

    1.2.2  代理模式实现

    /// <summary>

        /// 代理模式实现静态代理

        /// AOP在方法前后增加自定义的方法

        /// </summary>

        public class ProxyAOP

        {

            public static void Show()

            {

                User user = new User()

                {

                    Name = "XF",

                    Password = "1165"

                };

                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:{user.Name},Password:{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);

                }

                private void BeforeProceed(User user)

                {

                    Console.WriteLine("方法执行前");

                }

                private void AfterProceed(User user)

                {

                    Console.WriteLine("方法执行后");

                }

            }

        }

    1.3        动态代理AOP实现

    动态AOP可以通过Remoting/Castle(Emit)是实现。

    1.3.1  Remoting实现

    /// 使用.Net Remoting/RealProxy 实现动态代理

        /// 局限在业务类必须是继承自MarshalByRefObject类型

        public class RealProxyAOP

        {

            public static void Show()

            {

                User user = new User()

                {

                    Name = "XF",

                    Password = "116"

                };

                UserProcessor processor = new UserProcessor();

                processor.RegUser(user);

                Console.WriteLine("************************");

                UserProcessor userProcessor = TransparentProxy.Create<UserProcessor>();

                userProcessor.RegUser(user);

            }

            public interface IUserProcessor

            {

                void RegUser(User user);

            }

     

            public class XFRealProxy<T> : RealProxy

            {

                private T t;

                public XFRealProxy(T target) : base(typeof(T))

                {

                    this.t = target;

                }

                public override IMessage Invoke(IMessage msg)

                {

                    BeforeProceede(msg);

                    IMethodCallMessage callMessage = (IMethodCallMessage)msg;

                    object returnValue = callMessage.MethodBase.Invoke(this.t, 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("方法执行后加入逻辑");

                }

            }

            public static class TransparentProxy

            {

                public static T Create<T>()

                {

                    T instance = Activator.CreateInstance<T>();

                    XFRealProxy<T> realProxy = new XFRealProxy<T>(instance);

                    T transparentProxy = (T)realProxy.GetTransparentProxy();

                    return transparentProxy;

                }

            }

            /// <summary>

            /// 继承MarshalByRefObject父类,在支持远程处理的应用程序中,允许跨应用程序域边界访问对象。

            /// </summary>

            public class UserProcessor : MarshalByRefObject, IUserProcessor

            {

                public void RegUser(User user)

                {

                    Console.WriteLine($"用户已注册,用户名称{user.Name},密码:{user.Password}");

                }

            }

     

    }

    1.3.2  Castle实现

    /// <summary>

        /// 使用CastleDynamicProxy实现动态代理

        /// 方法是虚方法

        /// </summary>

        public class CastleProxyAOP

        {

            public static void Show()

            {

                User user = new User()

                {

                    Name = "XF",

                    Password = "12345"

                };

                ProxyGenerator generator = new ProxyGenerator();

                XFInterceptor interceptor = new XFInterceptor();

                UserProcessor userProcessor = generator.CreateClassProxy<UserProcessor>(interceptor);

                userProcessor.RegUser(user);

            }

            public interface IUserProcessor

            {

                void RegUser(User user);

            }

            public class UserProcessor : IUserProcessor

            {

                public virtual void RegUser(User user)

                {

                    Console.WriteLine($"用户注册,Name {user.Name},Password {user.Password}");

                }

            }

     

            public class XFInterceptor: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("方法执行后");

                }

            }

        }

    1.4        Unity、MVC中的AOP

    1.4.1  Unitiy实现AOP

    需要先在NuGet中引用如下组件:

    Unity、Unity.Interception、Unity.Configuration

    Unity.Interception.Configuration

    1.4.1.1      IUserProcessor

    定义接口

    public interface IUserProcessor

        {

            void RegUser(User user);

            User GetUser(User user);

    }

    1.4.1.2      UserProcessor

    接口的实现类

    public class UserProcessor:IUserProcessor

        {

            public void RegUser(User user)

            {

                Console.WriteLine("用户注册");

            }

            public User GetUser(User user)

            {

                return user;

            }

        }

    1.4.1.3      MonitorBehavior

    AOP添加的性能检测方法

    public class MonitorBehavior: Unity.Interception.InterceptionBehaviors.IInterceptionBehavior

        {

            public bool WillExecute

            {

                get { return true; }

            }

     

            public IEnumerable<Type> GetRequiredInterfaces()

            {

                return Type.EmptyTypes;

            }

     

            public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)

            {

                Console.WriteLine(this.GetType().Name);

                string methodName = input.MethodBase.Name;

                Stopwatch stopwatch = new Stopwatch();

                stopwatch.Start();

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

                stopwatch.Stop();

                Console.WriteLine($"{this.GetType().Name}统计方法{methodName}执行耗时{stopwatch.ElapsedMilliseconds}ms");

                return methodReturn;

            }      

        }

    1.4.1.4      LogBeforeBehavior

    AOP添加的日志记录方法

    public class LogBeforeBehavior : Unity.Interception.InterceptionBehaviors.IInterceptionBehavior

        {

            public bool WillExecute

            {

                get { return true; }

            }

     

            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());

                }

                return getNext().Invoke(input, getNext);

            }

    1.4.1.5      ParameterCheckBehavior

    AOP添加的参数检查方法

    public class ParameterCheckBehavior : Unity.Interception.InterceptionBehaviors.IInterceptionBehavior

        {

            public bool WillExecute { get { return true; } }

     

            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 < 3)

                    return input.CreateExceptionMethodReturn(new Exception("密码长度不能小于3位"));

                else

                {

                    Console.WriteLine("参数检测无误");

                    return getNext().Invoke(input, getNext);

                }

            }

        }

    1.4.1.6      CachingBehavior

    AOP添加的缓存方法

    public class CachingBehavior : Unity.Interception.InterceptionBehaviors.IInterceptionBehavior

        {

            public bool WillExecute

            {

                get { return true; }

            }

     

            public IEnumerable<Type> GetRequiredInterfaces()

            {

                return Type.EmptyTypes;

            }

     

            public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)

            {

                Console.WriteLine("CachingBehavior");

                if (input.MethodBase.Name.Equals("GetUser"))

                    return input.CreateMethodReturn(new User() { Id = 116, Name = "XF" });

                return getNext().Invoke(input, getNext);

            }

        }

    1.4.1.7      ExceptionLoggingBehavior

    AOP添加的异常记录方法

    public class ExceptionLoggingBehavior : Unity.Interception.InterceptionBehaviors.IInterceptionBehavior

        {

            public bool WillExecute

            {

                get { return true; }

            }

     

            public IEnumerable<Type> GetRequiredInterfaces()

            {

                return Type.EmptyTypes;

            }

     

            public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)

            {

                Console.WriteLine("ExceptionLoggingBehavior");

                IMethodReturn methodReturn = getNext().Invoke(input, getNext);

                if (methodReturn.Exception == null)

                    Console.WriteLine("无异常");

                else

                    Console.WriteLine($"异常:{methodReturn.Exception.Message}");

                return methodReturn;

            }

        }

    1.4.1.8      LogAfterBehavior

    AOP添加的日志记录方法

    public class LogAfterBehavior : Unity.Interception.InterceptionBehaviors.IInterceptionBehavior

        {

            public bool WillExecute

            {

                get { return true; }

            }

     

            public IEnumerable<Type> GetRequiredInterfaces()

            {

                return Type.EmptyTypes;

            }

     

            public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)

            {

                Console.WriteLine("LogAfterBehavior");

                foreach(var item in input.Inputs)

                {

                    Console.WriteLine(item.ToString());

                }

                IMethodReturn methodReturn = getNext().Invoke(input, getNext);

                Console.WriteLine("LogAfterBehavior" + methodReturn.ReturnValue);

                return methodReturn;

            }

        }

    1.4.1.9      UnityConfigAOP

    public class UnityConfigAOP

        {

            public static void Show()

            {

                User user = new User()

                {

                    Name = "XF",

                    Password = "116"

                };

                #region配置UnityContainer(通用代码)

                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 configurationSection = (UnityConfigurationSection)configuration.GetSection(UnityConfigurationSection.SectionName);

                configurationSection.Configure(container, "AOPContainer");

                #endregion

                IUserProcessor processor = container.Resolve<IUserProcessor>();

                processor.RegUser(user);

                processor.GetUser(user);

            }

        }

  • 相关阅读:
    ThinkPHP 中 where条件 or,and 同时使用
    mysql客户端 navicat 本地导入sql文件出错
    mysql查询出所有重复的记录
    JS返回上一页并刷新
    Jquery计算指定日期加上多少天、加多少月、加多少年的日期
    JS获取当前完整的url地址以及参数的方法
    PHP 计算两个时间戳之间相差的时间
    mysql左连接右连接(查询两张表不同的数据)
    C++中的C
    C++编程思想
  • 原文地址:https://www.cnblogs.com/Olive116/p/12451740.html
Copyright © 2011-2022 走看看