AOP

原文: AOP

版權聲明:本文爲博主原創文章,未經博主容許不得轉載。 https://blog.csdn.net/m0_37591671/article/details/80865029

AOP

1.什麼是AOP以及AOP能解決的問題

       在程序設計的過程當中,咱們利用OOP(面向對象的思想),在設計規模更大、邏輯更復雜的系統時,開發週期能變的更短。然而,面向對象設計的惟一問題是,它本質是靜態的,封閉的,任何需求的細微變化均可能對開發進度形成重大影響。
       設計模式能夠解決該問題。GOF將面向對象軟件的設計經驗做爲設計模式紀錄下來,它令人們能夠更加簡單方便地複用成功的設計和體系結構,幫助開發人員作出有利於系統複用的選擇。在設計的過程當中,經過各類模式體現了對象的行爲,暴露的接口,對象間關係,以及對象分別在不一樣層次中表現出來的形態。然而鑑於對象封裝的特殊性,「設計模式」的觸角始終在接口與抽象中大作文章,而對於對象內部則無能爲力。
       因此,AOP的設計思想就是針對這種問題出現的,在不破壞原有類型的前提下,給當前類增長新的功能。css

2.AOP的幾種實現方式

定義一個IUserProcessor的接口:前端

public interface IUserProcessor
    {
        void RegUser(User user);
        
}

定義一個UserProcessor的實現類:web

public class UserProcessor : IUserProcessor
    {
       

        public void RegUser(User user)
        {
//原始邏輯
            Console.WriteLine("用戶已註冊。Name:{0},PassWord:{1}", user.Name, user.Password);
        }
    }

2.12.1 裝飾器模式實現靜態AOP

定義一個UserProcessorDecorator類,實現IUserProcessor接口:設計模式

public  class UserProcessorDecorator:IUserProcessor
    {
        public 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 AfterProceed(User user)
        {
            Console.WriteLine("方法執行後");
        }

        private void BeforeProceed(User user)
        {
            Console.WriteLine("方法執行前");
        }
}

前端使用:markdown

User user = new User()
            {
                Name = "DZB",
                Password = "123123123123"
            };
            //普通方式註冊
            Console.WriteLine("*******普通方式註冊********");
            IUserProcessor processor = new UserProcessor();
            processor.RegUser(user);
            Console.WriteLine("*******靜態AOP方式註冊********");
            //靜態AOP方式註冊
            processor = new UserProcessorDecorator(processor);
        processor.RegUser(user);

雖然解決了易用性,可是咱們很快就發現了另外一些不盡人意的地方,裝飾器模式只能適用於 特定的類型,約束是比較強的。若是咱們但願咱們示例中的裝飾器能夠實現通用,就須要找別的方法了。ide

2.2 Net Remoting.Proxies的RealProxy 動態代理實現AOP

透明代理:svg

//透明代理
        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;
            }
        }

真實代理:繼承自RealProxy:this

//真實代理:繼承自RealProxy
        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);

                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("方法執行後能夠加入的邏輯");
            }
        }

侷限性:實現類UserProcessor必須繼承MarshalByRefObjectatom

public class UserProcessor : MarshalByRefObject, IUserProcessor
        {
            public void RegUser(User user)
            {
                Console.WriteLine("用戶已註冊。用戶名稱{0} Password{1}", user.Name, user.Password);
            }
        }

前端使用:spa

User user = new User()
            {
                Name = "DZB",
                Password = "123456"
            };
            Console.WriteLine("*********普通註冊************");
            UserProcessor processor = new UserProcessor();
            processor.RegUser(user);

            Console.WriteLine("********使用.Net Remoting.RealProxy動態代理實現*************");
            UserProcessor userProcessor = TransparentProxy.Create<UserProcessor>();
            userProcessor.RegUser(user);

2.3 Castle.DynamicProxy動態代理實現AOP

首先添加第三方Castle Nuget包:
這裏寫圖片描述
實現IInterceptor接口:

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("方法執行後");
            }
        }

侷限性:實現類中的方法必須帶上Virtual關鍵字:

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

前端使用:

User user = new User()
            {
                Name = "DZB",
                Password = "123456"
            };
            Console.WriteLine("*********普通方法註冊************");
            UserProcessor processor = new UserProcessor();
            processor.RegUser(user);

            Console.WriteLine("*******使用Castle.DynamicProxy動態代理實現**************");
            //添加Castle.Core的NUget包
            ProxyGenerator generator = new ProxyGenerator();
            MyInterceptor interceptor = new MyInterceptor();
            UserProcessor userprocessor = generator.CreateClassProxy<UserProcessor>(interceptor);
            userprocessor.RegUser(user);

2.4 Unity容器實現AOP

添加Unity包:
這裏寫圖片描述
添加一個UserHandler的特性,繼承自HandlerAttribute(來自Unity容器)

public class UserHandlerAttribute : HandlerAttribute
        {
            public override ICallHandler CreateHandler(IUnityContainer container)
            {
                ICallHandler handler = new UserHandler() { Order = this.Order };
                return handler;
            }
        }

特性對應的行爲:實現ICallHandler接口

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); //getNext.Invoke().Invoke(input, getNext);

                //Console.WriteLine("已完成操做");

                return methodReturn;
            }
        }

給須要添加額外行爲的類添加特性:

[UserHandlerAttribute(Order = 1)]
        public interface IUserProcessor
        {
            void RegUser(User user);
        }

前端使用:

User user = new User()
            {
                Name = "DZB",
                Password = "12345678957576"
            };
            {
                Console.WriteLine("**********普通註冊***********");
                UserProcessor processor = new UserProcessor();
                processor.RegUser(user);

                Console.WriteLine("*********************");
            }
            {
                //添加Unity容器
                Console.WriteLine("**********Unity註冊***********");
                IUnityContainer container = new UnityContainer();//聲明一個容器
                container.RegisterType<IUserProcessor, UserProcessor>();//聲明UnityContainer並註冊IUserProcessor
                IUserProcessor processor = container.Resolve<IUserProcessor>();
                processor.RegUser(user);//調用

                container.AddNewExtension<Interception>().Configure<Interception>()
                    .SetInterceptorFor<IUserProcessor>(new InterfaceInterceptor());


                //IUserProcessor userprocessor = new UserProcessor();
                IUserProcessor userprocessor = container.Resolve<IUserProcessor>();

                Console.WriteLine("********************");
                userprocessor.RegUser(user);//調用
}
相關文章
相關標籤/搜索