0%

本节目录:

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, null``, null``);

}

}

执行

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

if (!attrs)

{

base``.PerformProceed(invocation);

}

}

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

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 { get``; set``; }

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

}

}

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

container.Configure<Interception>().SetInterceptorFor<IPerson>(``new InterfaceInterceptor());

container.RegisterType<IPerson, Person>();

container.Resolve<IPerson>().Say();

}

Console.ReadKey();

}

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 如果觉得还有帮助的话,可以点一下右下角的【推荐】,希望能够持续的为大家带来好的技术文章!想跟我一起进步么?那就【关注】我吧。