中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

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

發布時間:2020-07-05 22:48:21 來源:網絡 閱讀:774 作者:鄒君安 欄目:網絡安全


AOP介紹

面向切面編程(Aspect Oriented Programming,英文縮寫為AOP),通過預編譯方式和運行期動態代理實現程序功能的統一維護的一種技術。

AOP是OOP的延續,是軟件開發中的一個熱點.

常用于:

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);

    }

}

執行

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有動態代理和靜態IL織入.

本節主要介紹動態代理方式,靜態可參考PostSharp.

 

Castle Core

原理:本質是創建繼承原來類的代理類.重寫虛方法實現AOP功能.

 

只需引用:

Install-Package Castle.Core

(在Castle的2.5以上版本,已經將 Castle.DynamicProxy2.dll 里有內容,集成到 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}方法,參數值:{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("攔截器調用方法前,方法名是:{0}。", invocation.Method.Name);

    }

    protected override void PerformProceed(IInvocation invocation)

    {

        Console.WriteLine("攔截器開始調用方法,方法名是:{0}。", invocation.Method.Name);

        var attrs = invocation.MethodInvocationTarget.Attributes.HasFlag(MethodAttributes.Abstract);//過濾abstract方法

        if (!attrs)

        {

            base.PerformProceed(invocation);//此處會調用真正的方法 invocation.Proceed();

        }

    }

    protected override void PostProceed(IInvocation invocation)

    {

        Console.WriteLine("攔截器調用方法后,方法名是:{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();  //實例化【攔截器】 

    //使用【代理類生成器】創建Person對象,而不是使用new關鍵字來實例化 

    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!");

     }

 }

 

啟用攔截器執行

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:代理實現基于.NET Remoting技術,它可攔截對象的所有函數。缺點是被攔截類型必須派生于MarshalByRefObject。

InterfaceInterceptor:只能對一個接口做攔截,好處時只要目標類型實現了指定接口就可以攔截。

VirtualMethodInterceptor:對virtual函數進行攔截。缺點是如果被攔截類型沒有virtual函數則無法攔截,這個時候如果類型實現了某個特定接口可以改用

 

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的成員,表示執行順序

    public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)

    {

        Console.WriteLine("方法執行前");

        //這之前插入方法執行前的處理

        var retvalue = getNext()(input, getNext);//在這里執行方法

        //這之后插入方法執行后的處理

        Console.WriteLine("方法執行后");

        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();

}


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

开封县| 安达市| 南部县| 富蕴县| 宁化县| 军事| 花垣县| 平潭县| 赤城县| 绥江县| 庐江县| 保山市| 乌拉特中旗| 房产| 长海县| 老河口市| 宕昌县| 锦州市| 汶上县| 慈利县| 洛川县| 金寨县| 馆陶县| 洮南市| 安康市| 中江县| 沾益县| 卢氏县| 万载县| 建阳市| 栾城县| 南川市| 丹阳市| 迁安市| 平乐县| 齐齐哈尔市| 西吉县| 云霄县| 邹平县| 柏乡县| 临泉县|