AOP介紹
成都創(chuàng)新互聯(lián)專注于平潭網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠為您提供平潭營銷型網(wǎng)站建設(shè),平潭網(wǎng)站制作、平潭網(wǎng)頁設(shè)計(jì)、平潭網(wǎng)站官網(wǎng)定制、重慶小程序開發(fā)服務(wù),打造平潭網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供平潭網(wǎng)站排名全網(wǎng)營銷落地服務(wù)。
面向切面編程(Aspect Oriented Programming,英文縮寫為AOP),通過預(yù)編譯方式和運(yùn)行期動(dòng)態(tài)代理實(shí)現(xiàn)程序功能的統(tǒng)一維護(hù)的一種技術(shù)。
AOP是OOP的延續(xù),是軟件開發(fā)中的一個(gè)熱點(diǎn).
常用于:
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有動(dòng)態(tài)代理和靜態(tài)IL織入.
本節(jié)主要介紹動(dòng)態(tài)代理方式,靜態(tài)可參考PostSharp.
Castle Core
原理:本質(zhì)是創(chuàng)建繼承原來類的代理類.重寫虛方法實(shí)現(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); //此處會(huì)調(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(); //實(shí)例化【代理類生成器】
var interceptor = new SimpleInterceptor(); //實(shí)例化【攔截器】
//使用【代理類生成器】創(chuàng)建Person對(duì)象,而不是使用new關(guān)鍵字來實(shí)例化
var person = generator.CreateClassProxy<Person>(interceptor);
Console.WriteLine( "當(dāng)前類型:{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
通過特性標(biāo)簽綁定
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默認(rèn)提供了三種攔截器:TransparentProxyInterceptor、InterfaceInterceptor、VirtualMethodInterceptor。
TransparentProxyInterceptor:代理實(shí)現(xiàn)基于.NET Remoting技術(shù),它可攔截對(duì)象的所有函數(shù)。缺點(diǎn)是被攔截類型必須派生于MarshalByRefObject。
InterfaceInterceptor:只能對(duì)一個(gè)接口做攔截,好處時(shí)只要目標(biāo)類型實(shí)現(xiàn)了指定接口就可以攔截。
VirtualMethodInterceptor:對(duì)virtual函數(shù)進(jìn)行攔截。缺點(diǎn)是如果被攔截類型沒有virtual函數(shù)則無法攔截,這個(gè)時(shí)候如果類型實(shí)現(xiàn)了某個(gè)特定接口可以改用
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();
}
|
網(wǎng)站名稱:[Solution]AOP原理解析及Castle、Autofac、Unity框架使用
當(dāng)前URL:http://jinyejixie.com/article24/jdosce.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站排名、域名注冊(cè)、動(dòng)態(tài)網(wǎng)站、關(guān)鍵詞優(yōu)化、服務(wù)器托管、定制開發(fā)
廣告
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源:
創(chuàng)新互聯(lián)