程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> 使用Unity實現AOP

使用Unity實現AOP

編輯:關於.NET

前提

引用以下文件

Microsoft.Practices.ObjectBuilder2.dll

Microsoft.Practices.Unity.dll

Microsoft.Practices.Unity.Configuration.dll

Microsoft.Practices.Unity.Interception.dll

Microsoft.Practices.Unity.Interception.Configuration.dll

Microsoft.Practices.Unity.StaticFactory.dll

可以從網站http://unity.codeplex.com/下載

本文中的實現類繼承於IOutput接口

1: public interface IOutput {
2:   void Output(int  x);
3: }

實現效果

我有兩個方法可以輸出字符串, 調用IOutput的實現類來輸出的,如:

1: class OutputImplement2 : IOutput {
2:   public void  Output(int x) {
3:     Console.WriteLine("output:{0}", x);
4:    }
5: }

調用它即在Main函數中

1: var op2=new OutputImplement2();
2: op2.Output(22);

即可,而AOP的作用是通過其它代碼,向op2.Output方法執行前或執行後注入其它執行 過程即最後形成的結果可能是:

這裡除了箭頭所指的一句外其它的都是注入進去這個方法的。

定義處理代碼

這裡我們先定義一段處理方法的代碼,Unity規定它是ICallHandler的一個實現

1: public class MyHandler : ICallHandler {
2:   public  int Order { get; set; }//這是ICallHandler的成員,表示執行順序
3:    public IMethodReturn Invoke(IMethodInvocation input,  GetNextHandlerDelegate getNext) {
4:     Console.WriteLine("方法名:  {0}", input.MethodBase.Name);
5:     Console.WriteLine("參 數:");
6:     for (var i = 0; i < input.Arguments.Count;  i++) {
7:       Console.WriteLine("{0}: {1}",  input.Arguments.ParameterName(i), input.Arguments[i]);
8:     }
9:      Console.WriteLine("執行");
10:     //這之前插入方法執行前的 處理
11:     var retvalue = getNext()(input, getNext);//在這裡執行 方法
12:     //這之後插入方法執行後的處理
13:      Console.WriteLine("完成");
14:     return retvalue;
15:   }
16: }

好,下面我們來看看怎麼把MyHandler與IOutput關聯起來,大體有2種方法

1.通過代碼直接關聯

這種實現方式比較“硬”。

它是利用Atrribute來實現這種關聯的,首先,先建一個Attribute。

1: public class MyHandlerAttribute : HandlerAttribute {
2:    public override ICallHandler CreateHandler(IUnityContainer container)  {
3:     return new MyHandler();//返回MyHandler
4:   }
5:  }

然後在IOutput的實現中使用如下代碼:

1: [MyHandler]
2: class OutputImplement1 : IOutput {
3:    public void Output(int x) {
4:     Console.WriteLine("重典執行 此方法輸出:{0}", x);
5:   }
6: }

這裡靠此Attribute就將二者關聯了起來

現在執行處寫:

1: var container1 = new UnityContainer()
2:    .AddNewExtension<Interception>()
3:   .RegisterType<IOutput,  OutputImplement1>();//聲明UnityContainer並注冊IOutput
4:  container1
5:   .Configure<Interception>()
6:    .SetInterceptorFor<IOutput>(new InterfaceInterceptor());
7: var  op1 = container1.Resolve<IOutput>();
8: op1.Output(11);//調用

That’s all OK.

2.用配置文件處理

如果用配置文件的話就不用Attribute了,所以實現的類如下

1: class OutputImplement2 : IOutput {
2:   public void  Output(int x) {
3:     Console.WriteLine("重典執行此方法輸出:{0}",  x);
4:   }
5: }

這裡不使用屬性來標記了,而使用配置文件,我們建一個名為Unity.xml的配置文件( 配置文件長,可以後看):

1: <?xml version="1.0" encoding="utf-8" ?>
2:  <configuration>
3:  <configSections>
4:   <section  name="unity"
5:         type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,
6:          Microsoft.Practices.Unity.Configuration,  Version=1.2.0.0,
7:         Culture=neutral,  PublicKeyToken=31bf3856ad364e35" />
8:  </configSections>
9:   <unity>
10:   <typeAliases>
11:    <typeAlias  alias="singleton"
12:          type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager,  Microsoft.Practices.Unity" />
13:    <typeAlias  alias="transparentProxy"
14:          type="Microsoft.Practices.Unity.InterceptionExtension.TransparentProxyIntercep tor, Microsoft.Practices.Unity.Interception" />
15:     <typeAlias alias="typeMatchingRule"
16:          type="Microsoft.Practices.Unity.InterceptionExtension.TypeMatchingRule,  Microsoft.Practices.Unity.Interception"/>
17:    <typeAlias  alias="interception"
18:          type="Microsoft.Practices.Unity.InterceptionExtension.Interception,  Microsoft.Practices.Unity.Interception"/>
19:    <typeAlias  alias="IOutput" type="ConsoleApplication1.IOutput,  ConsoleApplication1" />
20:    <typeAlias alias="MyHandler"  type="ConsoleApplication1.MyHandler, ConsoleApplication1" />
21:     <typeAlias alias="OutputImplement2"  type="ConsoleApplication1.OutputImplement2,  ConsoleApplication1" />
22:   </typeAliases>
23:    <containers>
24:    <container name="DefContainer">
25:      <types>
26:      <type type="IOutput"  mapTo="OutputImplement2" name="">
27:       <lifetime  type="singleton" />
28:      </type>
29:      </types>
30:    </container>
31:    </containers>
32:  </unity>
33:  </configuration>

最後我們來執行,要比第一種方法復雜一點:

1: var container2 = new UnityContainer ().AddNewExtension<Interception>();//聲明UnityContainer
2: var map  = new ExeConfigurationFileMap {ExeConfigFilename = "Unity.xml"};//使用 此配置文件
3: var config
4:  =  ConfigurationManager.OpenMappedExeConfiguration(map,  ConfigurationUserLevel.None);
5: var section
6:  =  (UnityConfigurationSection)config.GetSection("unity");//讀取配置文件節點
7:  section.Containers["DefContainer"].Configure(container2);
8:  container2.Configure<Interception>()
9:   .SetDefaultInterceptorFor<IOutput>(new TransparentProxyInterceptor ())
10:  .AddPolicy("LogMethod")
11:  .AddMatchingRule(new  TypeMatchingRule("IOutput"))
12:  .AddCallHandler(typeof (MyHandler));
13: var op2 = container2.Resolve<IOutput>();
14:  op2.Output(22);//調用

OK這時我們看到的結果就是:

來源:http://www.cnblogs.com/chsword/archive/2009/04/28/unity_aop.html

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved