C# 方法拦截器(Method Interceptor)是一种在运行时对方法进行拦截和处理的机制。它允许开发人员在方法执行之前和之后插入自定义逻辑,实现诸如日志记录、异常处理、性能监控等功能。
在 C# 中实现方法拦截器可以使用动态代理技术。以下是一种常用的实现方法拦截器的方式:
首先,请确保您的项目文件中包含了以下依赖项:
<ItemGroup>
<PackageReference Include="Castle.Core" Version="4.4.0" />
<PackageReference Include="Castle.DynamicProxy" Version="4.4.1" />
</ItemGroup>
然后使用以下代码来实现方法拦截器:
using Castle.DynamicProxy;
using System;
public class CustomInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
Console.WriteLine("Before method execution...");
invocation.Proceed();
Console.WriteLine("After method execution...");
}
}
public class MyService
{
public virtual void MyMethod()
{
Console.WriteLine("Inside MyMethod");
}
}
class Program
{
static void Main(string[] args)
{
ProxyGenerator generator = new ProxyGenerator();
MyService targetObject = new MyService();
MyService proxy = generator.CreateClassProxyWithTarget<MyService>(targetObject, new CustomInterceptor());
proxy.MyMethod();
}
}
这个修改后的代码在 MyService
类的 MyMethod
方法前后会分别执行 CustomInterceptor
中定义的逻辑。
当您运行这段代码时,将会看到如下输出:
Before method execution...
Inside MyMethod
After method execution...
在使用 Castle.DynamicProxy 库生成代理对象时,只有虚方法才能被成功地拦截。因此,如果您的目标对象的方法是非虚方法,则无法使用方法拦截器拦截该方法。
只有虚方法才会被成功拦截的原因是因为 Castle.DynamicProxy 库是通过使用继承和重写来实现代理拦截的。
当您使用 CreateClassProxyWithTarget 方法创建代理对象时,Castle.DynamicProxy库会生成一个派生自原始类的动态代理类。代理类将重写原始类中的虚方法,并将拦截器逻辑插入到这些重写的方法中。当您调用这些方法时,实际上将调用代理类中的重写方法,从而触发拦截器的逻辑。
由于非虚方法无法被继承和重写,因此无法直接对其进行拦截。在非虚方法上使用代理对象时,调用将直接转发给原始对象,而不会触发拦截器。
总结起来,只有使用了虚方法的类和方法,才能够被 Castle.DynamicProxy 库成功地拦截。因此,在使用方法拦截器时,如果您想要拦截某个方法,确保将其标记为 virtual 或 abstract(在抽象类和接口中)。