我无法让Castle Dynamic Proxy拦截显式接口实现的方法。我在这里阅读http://kozmic.pl/category/dynamicproxy/应该可以做到这一点。 这是我的课程;
internal interface IDomainInterface
{
string DomainMethod();
}
public class DomainClass : IDomainInterface
{
string IDomainInterface.DomainMethod()
{
return "not intercepted";
}
}
这是我的拦截器类;
public class DomainClassInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
if (invocation.Method.Name == "DomainMethod")
invocation.ReturnValue = "intercepted";
else
invocation.Proceed();
}
}
这是我的测试(失败);
[TestClass]
public void can_intercept_explicit_interface_implementation()
{
// Create proxy
var generator = new ProxyGenerator();
var interceptor = new DomainClassInterceptor();
var proxy = (IDomainInterface)generator.CreateClassProxy(typeof(DomainClass), interceptor);
// Invoke proxy method
var result = proxy.DomainMethod();
// Check method was intercepted -- fails
Assert.AreEqual("intercepted", result);
}
除了无法拦截显式接口实现之外,我似乎还没有收到不可代理成员的通知。 这是我的代理生成挂钩(充当间谍);
public class DomainClassProxyGenerationHook : IProxyGenerationHook
{
public int NonProxyableCount;
public void MethodsInspected() {}
public void NonProxyableMemberNotification(Type type, MemberInfo memberInfo)
{
NonProxyableCount++;
}
public bool ShouldInterceptMethod(Type type, MethodInfo methodInfo)
{
return true;
}
}
这是我的测试(再次失败);
[TestMethod]
public void receive_notification_of_nonproxyable_explicit_interface_implementation()
{
// Create proxy with generation hook
var hook = new DomainClassProxyGenerationHook();
var options = new ProxyGenerationOptions(hook);
var generator = new ProxyGenerator();
var interceptor = new DomainClassInterceptor();
var proxy = (IDomainInterface)generator.CreateClassProxy(typeof(DomainClass), options, interceptor);
// Check that non-proxyable member notification was received -- fails
Assert.IsTrue(hook.NonProxyableCount > 0);
}
有没有人成功让DP拦截显式接口实现?如果是这样,怎么样?
答案 0 :(得分:4)
您正在创建一个类代理。类代理只拦截类上的虚方法,并且C#中接口方法的显式实现不是虚拟的(因为它是私有的)。
如果要拦截接口上的方法,则需要明确告诉DynamicProxy
var proxy = (IDomainInterface)generator.CreateClassProxy(typeof(DomainClass), new Type[] { typeof(IDomainInterface) }, interceptor);
此外,您的界面已标记为internal
,因此请确保其为public
for DynamicProxy(将界面设为公开或添加InternalsVisibleToAttribute
)。
随着你的第一次测试将通过,该方法将被截获。