AOP原理解析及Castle、Autofac、Unity框架使用
轉(zhuǎn)自:https://www.cnblogs.com/neverc/p/5241466.html
AOP介紹
面向切面編程(Aspect Oriented Programming,英文縮寫為AOP),通過預編譯方式和運行期動態(tài)代理實現(xiàn)程序功能的統(tǒng)一維護的一種技術(shù)。
AOP是OOP的延續(xù),是軟件開發(fā)中的一個熱點.
常用于:
Authentication?
Caching
Lazy loading
Transactions
?
AOP基本原理
普通類
| 1 2 3 4 5 6 7 8 9 | class?Person : MarshalByRefObject { ????public?string?Say() ????{ ????????const?string?str =?"Person's say is called"; ????????Console.WriteLine(str); ????????return?str; ????} } |
代理類
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | public?class?Proxy<T> : RealProxy?where?T :?new() { ????private?object?_obj; ????public?Proxy(object?obj) ????????:?base(typeof(T)) ????{ ????????_obj = obj; ????} ????public?override?IMessage Invoke(IMessage msg) ????{ ????????Console.WriteLine("{0}:Invoke前", DateTime.Now); ????????var?ret = ((IMethodCallMessage)msg).MethodBase.Invoke(_obj,?null); ????????Console.WriteLine("{0}:Invoke后", DateTime.Now); ????????return?new?ReturnMessage(ret,?null, 0,?null,?null); ????} } |
執(zhí)行
| 1 2 3 4 5 6 7 8 9 10 | static?void?Main(string[] args) { ????var?per =?new?Proxy<Person>(new?Person()).GetTransparentProxy()?as?Person; ????if?(per !=?null) ????{ ????????var?str = per.Say(); ????????Console.WriteLine("返回值:"?+ str); ????} ????Console.ReadKey(); } |
?
AOP框架
AOP有動態(tài)代理和靜態(tài)IL織入.
本節(jié)主要介紹動態(tài)代理方式,靜態(tài)可參考PostSharp.
?
Castle Core
原理:本質(zhì)是創(chuàng)建繼承原來類的代理類.重寫虛方法實現(xiàn)AOP功能.
?
只需引用:
Install-Package Castle.Core
(在Castle的2.5以上版本,已經(jīng)將 Castle.DynamicProxy2.dll 里有內(nèi)容,集成到 Castle.Core.dll 中。)
?
Simple Class
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | public?abstract?class?Person { ????public?virtual?void?SayHello() ????{ ????????Console.WriteLine("我是{0}方法",?"SayHello"); ????} ????public?virtual?void?SayName(string?name) ????{ ????????Console.WriteLine("我是{0}方法,參數(shù)值:{1}",?"SayName", name); ????} ????public?abstract?void?AbstactSayOther(); ????public?void?SayOther() ????{ ????????Console.WriteLine("我是{0}方法",?"SayOther"); ????} } |
?
interceptor
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | public?class?SimpleInterceptor : StandardInterceptor { ????protected?override?void?PreProceed(IInvocation invocation) ????{ ????????Console.WriteLine("攔截器調(diào)用方法前,方法名是:{0}。", invocation.Method.Name); ????} ????protected?override?void?PerformProceed(IInvocation invocation) ????{ ????????Console.WriteLine("攔截器開始調(diào)用方法,方法名是:{0}。", invocation.Method.Name); ????????var?attrs = invocation.MethodInvocationTarget.Attributes.HasFlag(MethodAttributes.Abstract);//過濾abstract方法 ????????if?(!attrs) ????????{ ????????????base.PerformProceed(invocation);//此處會調(diào)用真正的方法 invocation.Proceed(); ????????} ????} ????protected?override?void?PostProceed(IInvocation invocation) ????{ ????????Console.WriteLine("攔截器調(diào)用方法后,方法名是:{0}。", invocation.Method.Name); ????} } |
?
Main
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | static?void?Main(string[] args) { ????var?generator =?new?ProxyGenerator();???????//實例化【代理類生成器】? ????var?interceptor =?new?SimpleInterceptor();??//實例化【攔截器】? ????//使用【代理類生成器】創(chuàng)建Person對象,而不是使用new關(guān)鍵字來實例化? ????var?person = generator.CreateClassProxy<Person>(interceptor); ????Console.WriteLine("當前類型:{0},父類型:{1}", person.GetType(), person.GetType().BaseType); ????Console.WriteLine(); ????person.SayHello();//攔截 ????Console.WriteLine(); ????person.SayName("Never、C");//攔截 ????Console.WriteLine(); ????person.SayOther();//普通方法,無法攔截???? ????person.AbstactSayOther();//抽象方法,可以攔截???? ????Console.ReadLine(); } |
?
Castle Windsor
特性式AOP
| 1 2 3 4 5 6 7 8 9 10 11 12 13 | public?interface?IPerson { ????void?Say(); } [Interceptor(typeof(LogInterceptor))] public?class?Person : IPerson { ????public?void?Say() ????{ ????????Console.WriteLine("Person's Say Method is called!"); ????} } |
?
| 1 2 3 4 5 6 7 8 9 | public?class?LogInterceptor : IInterceptor { ????public?void?Intercept(IInvocation invocation) ????{ ????????Console.WriteLine("{0}:攔截{1}方法{2}前,", DateTime.Now.ToString("O"), invocation.InvocationTarget.GetType().BaseType, invocation.Method.Name); ????????invocation.Proceed(); ????????Console.WriteLine("{0}:攔截{1}方法{2}后,", DateTime.Now.ToString("O"), invocation.InvocationTarget.GetType().BaseType, invocation.Method.Name); ????} } |
?
| 1 2 3 4 5 6 7 8 9 10 11 | static?void?Main(string[] args) { ????using?(var?container =?new?WindsorContainer()) ????{ ????????container.Register(Component.For<Person, IPerson>()); ????????container.Register(Component.For<LogInterceptor, IInterceptor>()); ????????var?person = container.Resolve<IPerson>(); ????????person.Say(); ????} ????Console.ReadKey(); } |
非侵入式AOP
| 1 2 3 4 5 6 7 8 9 10 11 12 | public?interface?IPerson { ????void?Say(); } public?class?Person : IPerson { ????public?void?Say() ????{ ????????Console.WriteLine("Person's Say Method is called!"); ????} } |
?
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | internal?static?class?LogInterceptorRegistrar { ????public?static?void?Initialize(WindsorContainer container) ????{ ????????container.Kernel.ComponentRegistered += Kernel_ComponentRegistered; ????} ????private?static?void?Kernel_ComponentRegistered(string?key, IHandler handler) ????{ ????????handler.ComponentModel.Interceptors.Add(new?InterceptorReference(typeof(LogInterceptor))); ????} } public?class?LogInterceptor : IInterceptor { ????public?void?Intercept(IInvocation invocation) ????{ ????????Console.WriteLine("{0}:攔截{1}方法{2}前,", DateTime.Now.ToString("O"), invocation.InvocationTarget.GetType().BaseType, invocation.Method.Name); ????????invocation.Proceed(); ????????Console.WriteLine("{0}:攔截{1}方法{2}后,", DateTime.Now.ToString("O"), invocation.InvocationTarget.GetType().BaseType, invocation.Method.Name); ????} } |
?
| 1 2 3 4 5 6 7 8 9 10 11 12 | static?void?Main(string[] args) { ????using?(var?container =?new?WindsorContainer()) ????{ ????????container.Register(Component.For<IInterceptor, LogInterceptor>());//先注入攔截器 ????????LogInterceptorRegistrar.Initialize(container); ????????container.Register(Component.For<IPerson, Person>()); ????????var?person = container.Resolve<IPerson>(); ????????person.Say(); ????} ????Console.ReadKey(); } |
?
Autofac
Install-Package Autofac.Aop
通過特性標簽綁定
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | class?LogInterceptor : IInterceptor ?{ ?????public?void?Intercept(IInvocation invocation) ?????{ ?????????Console.WriteLine("{0}:攔截{1}方法{2}前,", DateTime.Now.ToString("O"), invocation.InvocationTarget.GetType().BaseType, invocation.Method.Name); ?????????invocation.Proceed(); ?????????Console.WriteLine("{0}:攔截{1}方法{2}后,", DateTime.Now.ToString("O"), invocation.InvocationTarget.GetType().BaseType, invocation.Method.Name); ?????} ?} ?public?interface?IPerson ?{ ?????void?Say(); ?} ?[Intercept(typeof(LogInterceptor))] ?public?class?Person : IPerson ?{ ?????public?void?Say() ?????{ ?????????Console.WriteLine("Person's Say Method is called!"); ?????} ?} |
?
啟用攔截器執(zhí)行
| 1 2 3 4 5 6 7 8 9 10 11 | static?void?Main(string[] args) { ????var?builder =?new?ContainerBuilder(); ????builder.RegisterType<Person>().As<IPerson>().EnableInterfaceInterceptors(); ????builder.RegisterType<LogInterceptor>(); ????using?(var?container = builder.Build()) ????{ ????????container.Resolve<IPerson>().Say(); ????} ????Console.ReadLine(); } |
?
或采用非侵入性方法(去掉class上的特性仍可以)
| 1 2 3 4 5 6 7 8 9 10 11 | static?void?Main(string[] args) { ????var?builder =?new?ContainerBuilder(); ????builder.RegisterType<Person>().As<IPerson>().EnableInterfaceInterceptors().InterceptedBy(typeof(LogInterceptor)); ????builder.RegisterType<LogInterceptor>(); ????using?(var?container = builder.Build()) ????{ ????????container.Resolve<IPerson>().Say(); ????} ????Console.ReadLine(); } |
?
Unity
Unity默認提供了三種攔截器:TransparentProxyInterceptor、InterfaceInterceptor、VirtualMethodInterceptor。
TransparentProxyInterceptor:代理實現(xiàn)基于.NET Remoting技術(shù),它可攔截對象的所有函數(shù)。缺點是被攔截類型必須派生于MarshalByRefObject。
InterfaceInterceptor:只能對一個接口做攔截,好處時只要目標類型實現(xiàn)了指定接口就可以攔截。
VirtualMethodInterceptor:對virtual函數(shù)進行攔截。缺點是如果被攔截類型沒有virtual函數(shù)則無法攔截,這個時候如果類型實現(xiàn)了某個特定接口可以改用
?
Install-Package Unity.Interception
| 1 2 3 4 5 6 7 8 9 10 11 12 13 | public?class?MyHandler : ICallHandler { ????public?int?Order {?get;?set; }//這是ICallHandler的成員,表示執(zhí)行順序 ????public?IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext) ????{ ????????Console.WriteLine("方法執(zhí)行前"); ????????//這之前插入方法執(zhí)行前的處理 ????????var?retvalue = getNext()(input, getNext);//在這里執(zhí)行方法 ????????//這之后插入方法執(zhí)行后的處理 ????????Console.WriteLine("方法執(zhí)行后"); ????????return?retvalue; ????} } |
?
| 1 2 3 4 5 6 7 | public?class?MyHandlerAttribute : HandlerAttribute { ????public?override?ICallHandler CreateHandler(IUnityContainer container) ????{ ????????return?new?MyHandler();//返回MyHandler ????} } |
?
| 1 2 3 4 5 6 7 8 9 10 11 12 13 | public?interface?IPerson { ????void?Say(); } [MyHandler] public?class?Person : IPerson { ????public?virtual?void?Say() ????{ ????????Console.WriteLine("Person's Say Method is called!"); ????} } |
?
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | static?void?Main(string[] args) { ????using?(var?container =?new?UnityContainer()) ????{ ????????container.AddNewExtension<Interception>(); ????????//1.TransparentProxyInterceptor ????????//container.Configure<Interception>().SetInterceptorFor<IPerson>(new TransparentProxyInterceptor()); ????????//2.InterfaceInterceptor (使用1,2,3均可,這種侵入性最小) ????????container.Configure<Interception>().SetInterceptorFor<IPerson>(new?InterfaceInterceptor()); ????????//3.VirtualMethodInterceptor ????????//container.Configure<Interception>().SetInterceptorFor<Person>(new VirtualMethodInterceptor()); ????????container.RegisterType<IPerson, Person>(); ????????container.Resolve<IPerson>().Say(); ????} ????Console.ReadKey(); } |
轉(zhuǎn)載于:https://www.cnblogs.com/chenyishi/p/9676011.html
總結(jié)
以上是生活随笔為你收集整理的AOP原理解析及Castle、Autofac、Unity框架使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mac下设置redis开机启动方法
- 下一篇: Oracle中大批量删除数据的方法