AOP是一种编程模式,它允许在不改变应用程序业务逻辑的情况下,将横切关注点(Cross-Cutting Concerns)与应用程序业务逻辑分离。这种模式的优点是可以使代码更加模块化、可重用和易于维护。
使用Castle DynamicProxy进行拦截
Castle DynamicProxy 是一款运行时生成 .NET 代理的库。它可以动态地改变和扩展业务对象的行为,从而解耦横切关注点与核心领域模型,使得你的域模型更易于维护。无论你为任何组件指定拦截,Castle 都会自动创建代理,并通过拦截器将特定行为注入代理中。
nuget 下载安装Castle.Windsor
以下是 Castle DynamicProxy 中一些常用的方法和功能:
ProxyGenerator.CreateClassProxy<T>(params object[] constructorArguments)
:创建一个基于类 T
的代理对象。你可以通过 constructorArguments
参数传递给代理对象的构造函数。ProxyGenerator.CreateInterfaceProxyWithTarget<T>(T target, params IInterceptor[] interceptors)
:创建一个基于接口 T
的代理对象,并将 target
对象包装在代理中。你可以通过 interceptors
参数传递一个或多个拦截器来处理代理的方法调用。ProxyGenerator.CreateInterfaceProxyWithoutTarget<T>(params IInterceptor[] interceptors)
:创建一个基于接口 T
的代理对象,但不关联任何目标对象。你可以通过 interceptors
参数传递一个或多个拦截器。Component.For<T>()
:用于在 Windsor 容器中注册类型 T
。Interceptors<T>()
:在 Windsor 注册中,用于指定需要应用的拦截器类型 T
。DependsOn(Dependency.OnValue<T>(value))
:用于指定构造函数的依赖项,其中 T
是依赖项的类型,value
是依赖项的值。IInterceptor
接口:代表一个拦截器,可以在拦截对象的方法调用前后插入额外的逻辑。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();
}
}
我们可不可以统一管理呢,不然每次都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)
{
}
}
本文作者:技术老小子
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!