千家信息网

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

发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,AOP介绍面向切面编程(Aspect Oriented Programming,英文缩写为AOP),通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的
千家信息网最后更新 2026年10月31日[Solution] AOP原理解析及Castle、Autofac、Unity框架使用


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

container.Register(Component.For());

var person = container.Resolve();

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());//先注入拦截器

LogInterceptorRegistrar.Initialize(container);

container.Register(Component.For());

var person = container.Resolve();

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().As().EnableInterfaceInterceptors();

builder.RegisterType();

using (var container = builder.Build())

{

container.Resolve().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().As().EnableInterfaceInterceptors().InterceptedBy(typeof(LogInterceptor));

builder.RegisterType();

using (var container = builder.Build())

{

container.Resolve().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; }//这是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();

//1.TransparentProxyInterceptor

//container.Configure().SetInterceptorFor(new TransparentProxyInterceptor());

//2.InterfaceInterceptor (使用1,2,3均可,这种侵入性最小)

container.Configure().SetInterceptorFor(new InterfaceInterceptor());

//3.VirtualMethodInterceptor

//container.Configure().SetInterceptorFor(new VirtualMethodInterceptor());

container.RegisterType();

container.Resolve().Say();

}

Console.ReadKey();

}


方法 代理 拦截器 类型 函数 动态 实例 接口 特性 原理 普通 功能 对象 技术 方式 生成器 缺点 静态 处理 生成 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 南京欣网互联网络科技 中国互联网科技工作委员会毛军 新华互联网科技学校 国智互联网科技 互联网品科技 互联网科技公司发展 宜安科技 互联网金融 奇士达互联网科技 宁波青枫互联网科技有限公司 中国的互联网科技企业的崛起 福州新华互联网科技学校 知乎 欧洲十大科技互联网公司 字节跳动和互联网科技 中和天地互联网科技有限公司 互联网第三次科技革命特征 江苏互联网智能科技软件 南京一网一红互联网科技有限公司 互联网科技手机排行榜 科技互联网经济论坛 玉溪新华互联网科技怎么选 小米移动互联网科技园 深圳市人人互联网科技有限公司 互联网科技公司经营范围 盈实互联网科技 左右互联网络科技 茂名市互联网科技产业园 和信科技工业互联网 民营互联网公司国防科技 高科技互联网发展前景如何 黑科技 体验场景 互联网大会
0