AOP和IoC(微軟企業庫實現)


本文是講使用微軟企業庫來實現AOP和IoC/DI的,大家先裝下微軟企業庫5.0,地址:http://www.microsoft.com/en-us/download/details.aspx?id=15104

AOP的實現,使用PIAB(Policy Injection Application Block)

比如想給這個TestManager類的Method2方法檢查權限,有權限時才允許執行Method2方法體,最初的代碼如下:

public class TestManager
{
        public void Method2(int x)
        {
            Console.WriteLine("output222:{0}", x);
        }
}

 下面是改造后的代碼:

static class Identity//這個類純屬是為了權限而寫的一個很簡單的mock用戶是否login的類
{
        public static int UserID { get; set; }//如果UserID>0代表合法用戶
}
public class TestManager : MarshalByRefObject //這個MarshalByRefObject必須加上
{
        [PermissionCheckHandlerAttribute]     //在目標方法上加上自定義的Attribute(可以多個,就看需求了),這個Attribute必須繼承於HandlerAttribute public void Method2(int x)
        {
            Console.WriteLine("output222:{0}", x);
        }
}
    
public class PermissionCheckHandler : ICallHandler //這個類是最終AOP要掛載上去的,橫切邏輯就在這個類中,這個類必須實現ICallHandler
{
        public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
        {
            if(Identity.UserID>0)
                return getNext()(input, getNext);  //這句就代表繼續執行后續操作,這個后續操作也許是后續的AOP橫切點,也許是真正的業務方法調用(隨需求)

            return input.CreateExceptionMethodReturn(new Exception("Permission Denied"));  //當報錯需要拋異常時,需要用這個方法來生成,不能直接throw new exception
        }

        public int Order { get; set; }      //當多個AOP橫切點存在時,這個Order屬性代表優先順序,數字越低,優先級越高
}

[AttributeUsage(AttributeTargets.Method)]  //這句可以不寫 public class PermissionCheckHandlerAttribute : HandlerAttribute //這個class是最終被貼到業務方法上的Attribute,這個Attribute用來把{業務函數/方法 和 橫切點} 綁定起來
{

        public override ICallHandler CreateHandler(Microsoft.Practices.Unity.IUnityContainer container)
        {
            return new PermissionCheckHandler();    //返回橫切點class
        }
}

 

 最終調用的代碼:

            TestManager mgrProxy = PolicyInjection.Create<TestManager>();  //這個就是PIAB入口,能夠根據目標class生成代理

            Identity.UserID = 0;
            try
            {
                mgrProxy.Method2(1);
            }
            catch(Exception ex)
            {
                Console.WriteLine("1111111111111-->"+ex.Message);
            }

            Identity.UserID = 1;
            try
            {
                mgrProxy.Method2(2);
            }
            catch (Exception ex)
            {
                Console.WriteLine("2222222222222-->" + ex.Message);
            }

            Console.ReadKey();

 

運行如下:

 

下面來看看使用Unity時,IoC/DI的實現

初始代碼如下(一個interface, 分別有2個具體的實現,很簡單):

    public interface IManager
    {
        void Method1(int x);
    }
    public class Manager1 : IManager
    {
        public void Method1(int x)
        {
            Console.WriteLine("Manager1-->"+x);
        }
    }
    public class Manager2 : IManager
    {
        public void Method1(int x)
        {
            Console.WriteLine("Manager2-->" + x);
        }
    }

 

程序中,為了達到隔離的目的,只依賴接口,如下代碼:

IUnityContainer container = new UnityContainer();
container.RegisterType<IManager, Manager1>();
container.RegisterType<IManager, Manager2>("mgr2");  //當一個Interface擁有多個具體實現的時候,就需要用這種別名的形式標識了

IManager mgr = container.Resolve<IManager>();        //得到默認實例
mgr.Method1(1);

mgr = container.Resolve<IManager>("mgr2");           //得到命名實例
mgr.Method1(2);
Console.ReadKey();

 

運行如下:

 

下面我們來看看更加智能的IoC/DI

上面說的那個IManager的具體實現類,都是默認構造器,我們增加一個具體實現,如下:

public class Manager3 : IManager
    {
        private ILog log;
        public Manager3(ILog log)  //多了個依賴ILog,並且這個Manager3沒有默認構造器
        {
            this.log = log;
        }

        public void Method1(int x)
        {
            Console.WriteLine("Manager2-->" + x);
            log.Write(x.ToString());
        }
    }

 

咋辦呢?難道要Resolve ILog后,再手工放入Manager3?不用,哈哈,如下:

container.RegisterType<ILog, Log1>();                    //頁注冊一個Log進去
container.RegisterType<IManager, Manager3>("mgr3");      //注冊一個明明實例

mgr = container.Resolve<IManager>("mgr3");               //直接拉出一個mgr就好,一點都不麻煩,哈哈
mgr.Method1(3);
Console.ReadKey();

 運行如下:

 

AOP能結構化很多橫切點(日志、事務、權限等)

IoC/DI能簡化很多代碼...


免責聲明!

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



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