为什么我的拦截器在使用代理时没有被调用?
Why do my interceptors not called when using the proxy?
我正在尝试使用 Castle DynamicProxy,但是受 this one 等教程启发的最基本的代码片段失败了。
为了使事情更简单,我将 所有 代码放在一个文件中,所以它足够短,可以复制粘贴到这里:
namespace UnitTests
{
using Castle.DynamicProxy;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
[TestClass]
public class DemoTests
{
[TestMethod]
public void TestHelloMethodThroughProxy()
{
var proxy = new ProxyGenerator().CreateClassProxy<Demo>(new DemoInterceptor());
var actual = proxy.SayHello();
var expected = "Something other";
Assert.AreEqual(expected, actual);
}
}
[Serializable]
public class DemoInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
invocation.ReturnValue = "Something other";
}
}
public class Demo
{
public string SayHello()
{
return "Hello, World!";
}
}
}
该代码由单个单元测试组成,它生成 class 的代理,然后通过代理调用此 class 的方法。
代理旨在通过简单地分配结果值来绕过对原始方法的调用,而不调用原始方法。
如果我把invocation.ReturnValue = "Something other";
换成throw new NotImplementedException();
,测试的结果还是一模一样,没有抛出异常,说明代码可能没有被调用。在调试模式下,Intercept
方法中的断点也未到达。
我需要做什么才能调用拦截器?
Castle Windsor 只能拦截接口或虚拟成员。您的 Demo.SayHello
方法未标记为虚拟方法,因此未被拦截。
将方法标记为虚拟方法或使用接口。
参考Why can Windsor only intercept virtual or interfaced methods?
我正在尝试使用 Castle DynamicProxy,但是受 this one 等教程启发的最基本的代码片段失败了。
为了使事情更简单,我将 所有 代码放在一个文件中,所以它足够短,可以复制粘贴到这里:
namespace UnitTests
{
using Castle.DynamicProxy;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
[TestClass]
public class DemoTests
{
[TestMethod]
public void TestHelloMethodThroughProxy()
{
var proxy = new ProxyGenerator().CreateClassProxy<Demo>(new DemoInterceptor());
var actual = proxy.SayHello();
var expected = "Something other";
Assert.AreEqual(expected, actual);
}
}
[Serializable]
public class DemoInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
invocation.ReturnValue = "Something other";
}
}
public class Demo
{
public string SayHello()
{
return "Hello, World!";
}
}
}
该代码由单个单元测试组成,它生成 class 的代理,然后通过代理调用此 class 的方法。
代理旨在通过简单地分配结果值来绕过对原始方法的调用,而不调用原始方法。
如果我把invocation.ReturnValue = "Something other";
换成throw new NotImplementedException();
,测试的结果还是一模一样,没有抛出异常,说明代码可能没有被调用。在调试模式下,Intercept
方法中的断点也未到达。
我需要做什么才能调用拦截器?
Castle Windsor 只能拦截接口或虚拟成员。您的 Demo.SayHello
方法未标记为虚拟方法,因此未被拦截。
将方法标记为虚拟方法或使用接口。
参考Why can Windsor only intercept virtual or interfaced methods?