.NET知识梳理——8.AOP

Posted 墨遥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了.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>

    /// 使用Castle\\DynamicProxy实现动态代理

    /// 方法是虚方法

    /// </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.ElapsedMillisecondsms");

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

       

   

以上是关于.NET知识梳理——8.AOP的主要内容,如果未能解决你的问题,请参考以下文章

网络核心知识梳理(持续更新)

.NET知识梳理——5.委托

.NET知识梳理——5.委托

.NET知识梳理——7.Linq

.NET知识梳理——7.Linq

.NET知识梳理——6.lambda