前提
引用以下文件
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