1

我有这样的界面

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,而且有一天有人可以重构方法名称并且不再拦截该方法。

还有其他方法可以做到这一点吗?

4

1 回答 1

3

如果要为类创建代理,则需要使用classproxy。

如果你想排除某些成员,你必须使用 IProxyGenerationHook。

如果您希望您的代码对接口/类成员的更改(例如添加或删除的名称签名)不可知 - 不要这样做!

我能想到的最简单的代码是这样的:

private InterfaceMap interfaceMethods = typeof(YourClass).GetInterfaceMap(typeof(YourInterface));
public bool ShouldInterceptMethod(Type type, MethodInfo methodInfo)
{
   return Array.IndexOf(interfaceMethods.ClassMethods,methodInfo)!=-1;
}
于 2010-01-21T17:33:37.983 回答