我有一个像这样的界面
public interface IService
{
void InterceptedMethod();
}
实现该接口的类,还有另一个方法
public class Service : IService
{
public virtual void InterceptedMethod()
{
Console.WriteLine("InterceptedMethod");
}
public virtual void SomeMethod()
{
Console.WriteLine("SomeMethod");
}
}
和拦截器
public class MyInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
Console.WriteLine("Intercepting");
invocation.Proceed();
}
}
我想只拦截IService上存在的Service上的方法(即我想拦截InterceptedMethod()但不拦截SomeMethod()),但我不想使用来自IProxyGenerationHook的ShouldInterceptMethod。
我可以这样做,但由于它返回一个接口,我不能在这个对象上调用SomeMethod
var generator = new ProxyGenerator();
var proxy = generator.CreateInterfaceProxyWithTargetInterface<IService>(new Service(), new MyInterceptor());
proxy.InterceptedMethod(); // works
proxy.SomeMethod(); // Compile error, proxy is an IService
可以使用的一件事是从SomeMethod()中删除虚拟并执行此操作
var proxy = generator.CreateClassProxy<Service>(new MyInterceptor());
但我不喜欢这个解决方案。
我不喜欢使用来自IProxyGenerationHook的ShouldInterceptMethod,因为每次我更改界面时我都需要更改ShouldInterceptMethod,也有人有一天可以重构方法名称并且方法不再被截获。
还有其他方法吗?
答案 0 :(得分:2)
如果要为类创建代理,则需要使用classproxy。
如果要排除某些成员,则必须使用IProxyGenerationHook。
如果您希望您的代码与接口/类成员的更改无关,就像添加或删除名称签名一样 - 而不是这样做!
我能想到的最简单的代码是这样的:
private InterfaceMap interfaceMethods = typeof(YourClass).GetInterfaceMap(typeof(YourInterface));
public bool ShouldInterceptMethod(Type type, MethodInfo methodInfo)
{
return Array.IndexOf(interfaceMethods.ClassMethods,methodInfo)!=-1;
}