gpt4 book ai didi

c# - CaSTLe.Windsor : Changes for factories and interceptors in 3. 1?

转载 作者:太空宇宙 更新时间:2023-11-03 11:16:08 25 4
gpt4 key购买 nike

以下代码按原样通过 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,它使用工厂方法构建并注入(inject)到 Repository 中。

在我的真实代码中,我还使用了 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) 如何在不为工厂方法解析的对象生成代理的情况下保持我的拦截器注册?或者我猜想如何使用组件的工厂方法生成代理...

最佳答案

在 2.5.3 中,Windsor 似乎默默地未能应用拦截器。在 3.1.0 中,Windsor 在无法将拦截器应用于您已注册的类型时会抛出异常。 Windsor 使用他们的动态代理库通过生成您请求的实例的代理来支持拦截器 (AOP)。所以这两个版本的问题是你给它的类不能变成动态代理,因为它没有无参数构造函数。我认为 3.1.0 中的行为更正确,因为如果您期望应用拦截器,那么找出问题所在会困难得多。

如果您想保持 2.5.3 中的行为,但它会静默失败,只需在您的设施中注册拦截器之前添加一个检查以查看该类型是否可以被代理。这样做可能更好,但这是我想出的:

try
{
ProxyGenerator generator = new ProxyGenerator();
generator.CreateClassProxy(handler.ComponentModel.Implementation);
handler.ComponentModel.Interceptors.AddIfNotInCollection(InterceptorReference.ForType<MyInterceptor>());
}
catch {}

这在很多方面都是糟糕的代码,但它会重现您习惯的行为。请注意,当您实际上想要拦截器在不同的类上并且正在努力弄清楚为什么它没有被调用时,它不会咬住您。

关于c# - CaSTLe.Windsor : Changes for factories and interceptors in 3. 1?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12636311/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com