我在使用DynamicProxy2的Ninject拦截扩展时遇到问题。本质上,我的绑定对象的两个实例被创建。我的约束力是:
this.Bind<TestInterface1>().ToSelf().Intercept().With(new ActionInterceptor(i => Console.WriteLine("In interceptor")));
第一个实例似乎是作为正常解决程序的一部分创建的。第二个实例是作为代理创建的一部分创建的,特别是在 DynamicProxy3ProxyFactory.cs 中。
reference.Instance = this.generator.CreateClassProxy(targetType, ProxyOptions, parameters, wrapper);
第二个实例似乎取代了Ninject上下文中的第一个(虽然我不是100%肯定),所以人们会相信一切都没问题。第一个实例只有一纳秒左右。不幸的是,我的构造函数并不是那么“干净”并且运行两次导致一些混乱。由于第二个实例的构建是在Castle中完成的,我不知道是否有办法绕过这个,但任何建议都会受到赞赏(重写构造函数已被考虑并击落:))。
答案 0 :(得分:1)
我不认为雷莫的答案是正确的。它看起来像“代理”如何工作。如果我们直接在下面的简单代码中使用Castle,则很明显,正在创建继承用户类的子类,而实际上并不需要第二个实例。 所以,由于我不知道的原因,两个实例似乎是Ninject拦截设计的最终结果。
用于Ninject拦截的两个实例看起来像Ninject设计的最终结果,其中Proxies Generator实际上是在实例创建后就可以工作的“激活策略”(Ninject.Activation.Strategies.ActivationStrategy
),因此它别无其他选择,而是创建另一个(代理)实例。这样做的原因也可能很公平,因为关于实例构造的所有细微差别仅是容器本身已知的,并且像这样的“扩展”(如不同的“激活策略”)被有意地与该方面分开。
void Main()
{
var x = new ProxyGenerator().CreateClassProxy(typeof(Test), new Interceptor()) as Test;
}
public class Test
{
public Test()
{
$"ctor for {GetType().FullName} base is {GetType().BaseType.FullName}".Dump();
}
}
输出为(单行,单个实例):
Castle.Proxies.TestProxy库的ctor是UserQuery + Test
答案 1 :(得分:0)
您似乎无法理解使用动态代理的拦截是如何工作的。动态代理是一个新类,它派生自截获的类/接口,并将所有调用转发给截获的类/接口。
e.g。
class A{ }
class AProxy : A {}
现在创建了两个类的实例。因为AProxy调用基础构造函数,所以您会看到构造函数的两次调用。您还假设立即收集一个实例是错误的。它们的寿命完全相同。
最干净的解决方案是解决无法调用构造函数两次的问题。这是一个强烈的迹象,表明存在严重错误。其他可能性是使用2.3beta并使用接口而不是类或将问题代码放入初始化方法,该方法仅由真实类调用,而不是代理调用。