1

我在使用带有 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 中完成的,我不知道是否有办法解决这个问题,但任何建议都将不胜感激(重写构造函数已被考虑并被击落:))。

4

2 回答 2

1

您似乎不了解使用动态代理进行拦截的工作原理。动态代理是一个新类,它派生自被拦截的类/接口,并将所有调用转发到被拦截的类/接口。

例如

class A{ }
class AProxy : A {}

现在创建了两个类的实例。因为 AProxy 调用基本构造函数,所以您会看到构造函数的两次调用。您还假设立即收集一个实例是错误的。它们的寿命完全相同。

最干净的解决方案是解决你的构造函数不能被调用两次的问题。这是一个强烈的迹象,表明存在严重错误。其他可能性是使用 2.3beta 并使用接口而不是类或将问题代码放入初始化方法中,该方法仅由真实类而不是代理调用。

于 2011-07-16T21:31:48.007 回答
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

于 2020-02-12T20:44:41.260 回答