Unity.Interception(AOP)


        在前面我們學習到的是Unity依賴注入(DI)與統一容器來松散耦合,這個設計已經對我們系統帶來了很多的好處。但是我們還會想嘗試和遵循單一職責,開放封閉原則。比如我們不應該在我們的Business層去實現日志、校驗、緩存、異常處理等工作,Unity的Interception可以幫助我們橫切關注點(Crosscutting concerns 即AOP),來獨立處理這些關注點。
         什么是橫切關注點(AOP)?橫切關注點(AOP)是關注影響應用程序的許多區域。例如,你可能需要將信息寫入日志文件在應用程序許多不同的區域,橫切關注點(AOP)可以幫助你構建一致的應用程序方式與應用程序業務。
常見的LOB應用程序的橫切關注點包括:
         1.日記(Log)
         2.校驗(Validation
         3.異常處理(Exception handling
         4.瞬時故障處理(Transient fault handling
         5.權限處理(Authentication and authorization
         6.緩存(Caching
         7.性能監控(Performance monitoring
         8.加密(Encryption
         9.映射(Mapping
         10.壓縮(Compression
 
        在使用Unity.Interception以前我們先自己寫一個簡單的AOP:
1.業務接口
    /// <summary>
    /// 接口
    /// </summary>
    public interface ITalk
    {
        void talk(string msg);
    }

2.業務實現

    public class PeopleTalk : ITalk
    {
        private string username;

        private int age;

        public string UserName
        {
            get { return username; }
        }

        public int Age
        {
            get { return age; }
        }

        public PeopleTalk(string userName, int age)
        {
            this.username = userName;
            this.age = age;
        }

        public virtual void talk(string msg)
        {
            Console.WriteLine(msg + "!你好,我是" + username + ",我的年齡" + age);
        }

    }

3.代理對象

    public class TalkProxy : ITalk
    {
        private ITalk talker;

        public TalkProxy(ITalk talker)
        {
            this.talker = talker;
        }

        public void talk(string msg)
        {
            talker.talk(msg);
        }

        public void talk(string msg, string singName)
        {
            talker.talk(msg);
            sing(singName);
        }

        public void sing(string singName)
        {
            Console.WriteLine("唱歌:" + singName);
        }
    }

4.調用

    class Program
    {
        static void Main(string[] args)
        {
            #region 靜態代理

            ITalk people = new PeopleTalk("AOP", 18);

            people.talk("No ProXY Test!");

            Console.WriteLine("---------------------------------");

            TalkProxy talker = new TalkProxy(people);

            talker.talk("ProXY Test", "代理");

            #endregion

        }
    }

  代理模式是一種簡單的AOP,talk是一個切面,我們可以在代理類中添加日志、校驗、異常處理等等。這樣我們就實現了,核心關注點與橫切關注點的分離。正如Avanade公司的高級方案架構師Adam Magee所說,AOP的核心思想就是”將應用程序中的商業邏輯同對其提供支持的通用服務進行分離“。

 

  下面我們來看看 Unity.Interception是如何現實AOP的
 1.在Unity中實現IInterceptionBehavior接口
    /// <summary>
    /// Unity為我們提供了一個IInterceptionBehavior接口需要實現這個接口
    /// 接口為我們提供了三個方式(GetRequiredInterfaces、Invoke、WillExecute)實現
    /// WillExecute表示是否執行該行為,如果是false這個方法被調用時,不會被捕捉。因為我們總是要執行的,所以為true
    /// GetRequiredInterfaces將你想要的接口類型和行為聯系起來,我們暫時不需要,所以返回Type.EmptyTypes
    /// Invoke執行方式接口
    /// </summary>
    public class LoggingInterceptionBehavior : IInterceptionBehavior
    {
        public bool WillExecute
        {
            get { return true; }
        }

        public IEnumerable<Type> GetRequiredInterfaces()
        {
            return Type.EmptyTypes;
        }

        public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
        {
            Console.WriteLine("Method: {0}", input.MethodBase.Name);

            Console.WriteLine("參數:");
            for (var i = 0; i < input.Arguments.Count; i++)
            {
                Console.WriteLine("{0}: {1}", input.Arguments.ParameterName(i), input.Arguments[i]);
            }
            Console.WriteLine("執行前");
            var result = getNext()(input, getNext);//在這里執行方法
            if (result.Exception != null)
            {
                //發生錯誤記錄日志
                Console.WriteLine(String.Format("Method {0} threw exception {1} at {2}", input.MethodBase, result.Exception.Message, DateTime.Now.ToLongTimeString()));
            }
            Console.WriteLine("執行后");
            return result;
        }
    }

2.調用

    class Program
    {
        static void Main(string[] args)
        {
            UnityContainer container = new UnityContainer();
            container.AddNewExtension<Interception>();
            container.RegisterType<ITalk, PeopleTalk>(
                new InjectionConstructor("AOP", 18), 
                new Interceptor<InterfaceInterceptor>(), 
                new InterceptionBehavior<LoggingInterceptionBehavior>());
            ITalk talker = container.Resolve<ITalk>();
            talker.talk("ProXY Test!");
        }
    }

以上基本完成了簡單的Unity.Interception 

當然在Unity中不只有InterfaceInterceptor一種攔截器,它還包含其它兩種攔截器:TransparentProxyInterceptor 與 VirtualMethodInterceptor 

這里就不詳細介紹就提一下這三種:

InterfaceInterceptor只要是繼承接口的方法都會被攔截。
TransparentProxyInterceptor只要是繼承類使用的方法都會被攔截。
VirtualMethodInterceptor 意思是虛方法攔截器,繼承類的方法必須是Virtual的,和繼承類必須是公開的。滿足這兩個條件即可

 
 
 
----------------------------------------------------------------------------------------------------------------
 
同時在這里我還是沒有回答在我 Unity4.0的使用 中“一只老菜鳥”所提的問題,不過我會努力的
以上是本人比較初級的處理,主要用於本人學習Unity的一個記錄

如果有不懂的可以先查看

Unity 依賴注入之一

Unity 依賴注入之二

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM