Ninject Interception扩展正在创建该类的2个实例;有没有办法避免这种情况

时间:2011-07-12 21:05:03

标签: ninject ninject-extensions

我在使用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中完成的,我不知道是否有办法绕过这个,但任何建议都会受到赞赏(重写构造函数已被考虑并击落:))。

2 个答案:

答案 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并使用接口而不是类或将问题代码放入初始化方法,该方法仅由真实类调用,而不是代理调用。