[Solution]AOP原理解析及Castle、Autofac、Unity框架使用



AOP介紹

成都創(chuàng)新互聯(lián)專注于平潭網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠(chéng)為您提供平潭營(yíng)銷型網(wǎng)站建設(shè),平潭網(wǎng)站制作、平潭網(wǎng)頁(yè)設(shè)計(jì)、平潭網(wǎng)站官網(wǎng)定制、重慶小程序開發(fā)服務(wù),打造平潭網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供平潭網(wǎng)站排名全網(wǎng)營(yíng)銷落地服務(wù)。

面向切面編程(Aspect Oriented Programming,英文縮寫為AOP),通過(guò)預(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, nullnull);

    }

}

執(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)建繼承原來(lái)類的代理類.重寫虛方法實(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);//過(guò)濾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)鍵字來(lái)實(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();//普通方法,無(wú)法攔截    

    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

通過(guò)特性標(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ù)則無(wú)法攔截,這個(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 { getset; }//這是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://muchs.cn/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)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

手機(jī)網(wǎng)站建設(shè)