以下代码在 Castle.Windsor 2.5.3 中按原样通过,但在升级到 3.1.0 后失败
异常是 InvalidProxyConstructorArgumentsException,它指出“无法实例化类的代理:测试。找不到无参数的构造函数。”
static void Main(string[] args)
{
var container = new WindsorContainer();
container.Register(Component.For<Interceptor>(),
Component.For<Test>().UsingFactoryMethod(() => new Test(""))
.Interceptors<Interceptor>());
var test = container.Resolve<Test>(); //THROWS IN 3.1.0
}
}
public class Test
{
public readonly string S;
public Test(string s)
{
S = s;
}
}
public class Interceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
invocation.Proceed();
}
}
在我的真实代码中,Test 是一个使用工厂方法构建并注入到存储库中的 MongoDatabase。
在我的真实代码中,我还使用 AbstractFacility 的继承者来注册拦截器。这样我就不必为每个组件注册拦截器。两种形式的拦截器使用似乎在以后的解决方案中都以相同的方式工作/失败(在 2.5.3/3.1.0 中)。以下是该设施的简化版本供参考:
public class Facility : AbstractFacility
{
protected override void Init() { Kernel.ComponentRegistered += KernelComponentRegistered; }
static void KernelComponentRegistered(string key, IHandler handler)
{
if (typeof(IInterceptor).IsAssignableFrom(handler.ComponentModel.Implementation)) return;
handler.ComponentModel.Interceptors.AddIfNotInCollection(InterceptorReference.ForKey("SomeInterceptor"));
}
}
我查看了 Castle.Windsor 源代码,抛出的代码期望在给定的类周围包装一个代理,这就是它寻找无参数构造函数的原因。但是在 2.5.3 中,我认为代理生成代码从未被执行,并且容器(在我看来是正确的)解析为 Test/MongoDatabase 的非代理版本
所以我猜有两个问题:1)发生了什么变化?2)如何在不为工厂方法解析的对象生成代理的情况下保留我的拦截器注册?或者我猜想如何使用组件的工厂方法生成代理......