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