编辑
2025-09-25
C#
00

目录

摘要
正文

摘要

AOP是一种编程模式,它允许在不改变应用程序业务逻辑的情况下,将横切关注点(Cross-Cutting Concerns)与应用程序业务逻辑分离。这种模式的优点是可以使代码更加模块化、可重用和易于维护。

正文

使用Castle DynamicProxy进行拦截

Castle DynamicProxy 是一款运行时生成 .NET 代理的库。它可以动态地改变和扩展业务对象的行为,从而解耦横切关注点与核心领域模型,使得你的域模型更易于维护。无论你为任何组件指定拦截,Castle 都会自动创建代理,并通过拦截器将特定行为注入代理中。

image.png

nuget 下载安装Castle.Windsor

以下是 Castle DynamicProxy 中一些常用的方法和功能:

  1. ProxyGenerator.CreateClassProxy<T>(params object[] constructorArguments):创建一个基于类 T 的代理对象。你可以通过 constructorArguments 参数传递给代理对象的构造函数。
  2. ProxyGenerator.CreateInterfaceProxyWithTarget<T>(T target, params IInterceptor[] interceptors):创建一个基于接口 T 的代理对象,并将 target 对象包装在代理中。你可以通过 interceptors 参数传递一个或多个拦截器来处理代理的方法调用。
  3. ProxyGenerator.CreateInterfaceProxyWithoutTarget<T>(params IInterceptor[] interceptors):创建一个基于接口 T 的代理对象,但不关联任何目标对象。你可以通过 interceptors 参数传递一个或多个拦截器。
  4. Component.For<T>():用于在 Windsor 容器中注册类型 T
  5. Interceptors<T>():在 Windsor 注册中,用于指定需要应用的拦截器类型 T
  6. DependsOn(Dependency.OnValue<T>(value)):用于指定构造函数的依赖项,其中 T 是依赖项的类型,value 是依赖项的值。
  7. IInterceptor 接口:代表一个拦截器,可以在拦截对象的方法调用前后插入额外的逻辑。
  8. IInvocation 接口:代表一个方法调用的上下文,可以通过 invocation.Method 获取被调用的方法信息,通过 invocation.Arguments 获取方法参数。

IWorker接口

C#
public interface IWorker { string Name { get; set; } string Start(); string Stop(); }

Worker类

C#
public class Worker : IWorker { public string Name { get; set; } public string Start() { return this.Name + "开始工作了!"; } public string Stop() { return this.Name + "结束工作了!"; } }

LoggingInterceptor 拦截器

C#
public class LoggingInterceptor : IInterceptor { public Action<string, string> callback; public void Intercept(IInvocation invocation) { string methodName = invocation.Method.Name; //记录日志 if (callback != null) { callback("开始调用" + methodName, String.Join(",", invocation.Arguments) + ":" + DateTime.Now); } invocation.Proceed(); if (callback != null) { callback("结束调用" + methodName, String.Join(",", invocation.Arguments) + ":" + invocation.ReturnValue +":" + DateTime.Now); } } }

其中invocation.Proceed(); 就是调用源方法

C#
public partial class Form1 : Form { ProxyGenerator generator = new ProxyGenerator(); LoggingInterceptor logging = new LoggingInterceptor(); public Form1() { InitializeComponent(); logging.callback = (x, y) => { txtLog.AppendText(x + ":" + y); txtLog.AppendText(System.Environment.NewLine); }; } private void btnStart_Click(object sender, EventArgs e) { Worker worker=new Worker(); worker.Name = "张三"; IWorker service = generator.CreateInterfaceProxyWithTarget<IWorker>(new Worker(), logging); service.Start(); } }

image.png

我们可不可以统一管理呢,不然每次都CreateInterfaceProxyWithTarget 包装不合适

修改LoggingInterceptor

C#
public class LoggingInterceptor : IInterceptor { private Action<string,string> callback; public LoggingInterceptor(Action<string, string> callback) { this.callback = callback; } public void Intercept(IInvocation invocation) { string methodName = invocation.Method.Name; //记录日志 if (callback != null) { callback("开始调用" + methodName, String.Join(",", invocation.Arguments) + ":" + DateTime.Now); } invocation.Proceed(); if (callback != null) { callback("结束调用" + methodName, String.Join(",", invocation.Arguments) + ":" + invocation.ReturnValue +":" + DateTime.Now); } } }

修改Form

C#
public partial class Form1 : Form { public Action<string,string> LogCallBack; WindsorContainer container = new WindsorContainer(); public Form1() { InitializeComponent(); LogCallBack = (x, y) => { txtLog.AppendText(x + ":" + y); txtLog.AppendText(System.Environment.NewLine); }; // 注册 LoggingInterceptor 服务,并指定构造函数的依赖项 container.Register(Component.For<LoggingInterceptor>() .DependsOn(Castle.MicroKernel.Registration.Dependency.OnValue<Action<string,string>>(LogCallBack))); //将LoggingInterceptor 附加到Worker上 container.Register( Component.For<IWorker>() .ImplementedBy<Worker>() .Interceptors<LoggingInterceptor>()); } private void btnStart_Click(object sender, EventArgs e) { var worker = container.Resolve<IWorker>(); worker.Name = "李四"; worker.Start(); } private void Form1_Load(object sender, EventArgs e) { } }

image.png

本文作者:技术老小子

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!