1. 程式人生 > >使用.net core中的類DispatchProxy實現AOP

使用.net core中的類DispatchProxy實現AOP

在軟體業,AOP為Aspect Oriented Programming的縮寫,意為:面向切面程式設計,通過預編譯方式和執行期動態代理實現程式功能的統一維護的一種技術。AOP是軟體開發中的一個熱點,利用AOP可以對業務邏輯的各個部分進行隔離,從而使得業務邏輯各部分之間的耦合度降低,提高程式的可重用性。

比如說三層的呼叫:UI => BLL => DAL,正常來說我們會在UI層呼叫BLL層某個類的某個方法,然後BLL層某個類的某個方法又會呼叫DAL層某個類的某個方法,可以說通常情況下我們都是這麼幹的;如果說UI調BLL、BLL調DAL是縱向的話,那麼AOP就是橫向的,AOP可以做到在呼叫BLL層或DAL層任意方法之前之後做一些統一的邏輯處理。

AOP的典型應用場景:日誌記錄、許可權驗證、異常處理、快取等

目前,可以實現AOP的類庫也有很多,如下:

AspectCore
Unity
Castle DynamicProxy
Dora.Interception

 

但是在.net core中有DispatchProxy類(名稱空間:System.Reflection),提供例項化代理物件和處理其方法排程的機制,藉助它我們可以自己實現AOP,直接看示例

 

定義一個訊息介面IMessage,其中有一個傳送訊息Send和接收訊息Receive的方法定義:

    public interface IMessage
    {
        void Send(string content);
        void Receive(string content);
    }

 

定義電子郵件類EmailMessage實現訊息介面IMessage,實現使用電子郵件傳送和接收訊息:

    public class EmailMessage : IMessage
    {
        public void Send(string content)
        {
            Console.WriteLine("Send Email:" + content);
        }
        public void Receive(string content)
        {
            Console.WriteLine("Receive Email:" + content);
        }
    }

 

定義日誌攔截器LogDispatchProxy 繼承自DispatchProxy類,重寫基類Invoke方法並在目標方法呼叫前後加上所需業務邏輯;然後定義TargetClass屬性,該屬性是目標方法所屬類的例項

    public class LogDispatchProxy : DispatchProxy
    {
        public object TargetClass { get; set; }
        protected override object Invoke(MethodInfo targetMethod, object[] args)
        {
            Write("方法執行前");
            var result = targetMethod.Invoke(TargetClass, args);
            Write("方法執行後");
            return result;
        }

        private void Write(string content)
        {
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine(content);
            Console.ResetColor();
        }
    }

 

使用:

    class Program
    {
        static void Main(string[] args)
        {
            //使用DispatchProxy類的靜態方法Create生成代理類,其中Create是個泛型方法,泛型有兩個值,第一個值必須是介面,第二個值必須是DispatchProxy的子類
            IMessage messageDispatchProxy = DispatchProxy.Create<IMessage, LogDispatchProxy>();
            //建立一個實現了IMessage介面的類的例項,並賦值給代理類的TargetClass屬性
            ((LogDispatchProxy)messageDispatchProxy).TargetClass = new EmailMessage();
            messageDispatchProxy.Send("早上好");
            messageDispatchProxy.Receive("中午好");

            Console.ReadKey();
        }
    }

 

執行結果

我的理解:通過DispatchProxy.Create建立的代理類messageDispatchProxy 就是一個LogDispatchProxy類,並且利用我們提供的的例項實現了IMessage介面,所以messageDispatchProxy可以強轉為LogDispatchProxy或IMessage

至此,我們沒有通過任何第三方類庫,自己實現了一