Ninject Interception 扩展正在创建该类的 2 个实例;有没有办法避免这种情况
我在使用 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 中完成的,我不知道是否有办法解决这个问题,但任何建议将不胜感激(重写构造函数已被考虑并被否决:))。
I have a problem using the Ninject interception extension with DynamicProxy2. In essence, two instances of my bind-to object get created. My binding is:
this.Bind<TestInterface1>().ToSelf().Intercept().With(new ActionInterceptor(i => Console.WriteLine("In interceptor")));
The first instance seems to be created as part of the normal resolution procedure. The second instance gets created as part of the proxy creation, specifically in DynamicProxy3ProxyFactory.cs.
reference.Instance = this.generator.CreateClassProxy(targetType, ProxyOptions, parameters, wrapper);
The second instance seems to replace the first in the Ninject context (although I'm not 100% sure about that), so one would believe that everything's OK. The first instance would only be around for a nanosecond. Unfortunately, my constructors aren't that 'clean' and running it twice is causing some confusion. As the construction of the second instance is being done in Castle, I don't know if there is a way around this, but any advice would be appreciated (rewrite the constructors has been thought of and shot down :) ).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
看来您不了解使用动态代理进行拦截的工作原理。动态代理是从被拦截的类/接口派生的新类,并将所有调用转发到被拦截的类/接口。
例如,
现在创建了两个类的实例。因为 AProxy 调用基本构造函数,所以您会看到构造函数的两次调用。另外,您假设立即收集一个实例是错误的。他们有完全相同的寿命。
最干净的解决方案是解决构造函数不能被调用两次的问题。这是一个强烈的迹象,表明出现了严重错误。其他可能性是使用 2.3beta 并使用接口而不是类,或者将问题代码放入初始化方法中,该方法仅由真实类而不是代理调用。
It seems you do not understand how interception using dynamic proxies works. A dynamic proxy is a new class that derives from the intercepted class/interface and forwards all calls to the intercepted class/interface.
e.g.
An instance of both classes gets now created. Because AProxy calls the base constructor you see two calls of the constructor. Also you assumption that one instance is immediately collected is wrong. They have exactly the same lifetime.
The cleanest solution is to solve the problem that your constructor can't be called twice. This is a strong sign that there is something terribly wrong. Other possibilities are using the 2.3beta and using an interface instead of a class or putting the problem code into an initialization method which gets called by the real class only but not the proxy.
我认为雷莫的回答并不切题。它看起来不像“代理”是如何工作的。如果我们通过下面的简单代码直接使用 Castle,很明显会创建继承用户类的子类,并且实际上不需要第二个实例。
因此,出于我不知道的原因,两个实例似乎是 Ninject 拦截设计的最终结果。Ninject 拦截的两个实例看起来像是 Ninject 设计的最终结果,其中 Proxies Generator 实际上是一个“激活策略”(
Ninject.Activation.Strategies.ActivationStrategy
)在实例创建之后起作用,因此它没有其他选择,只能创建另一个(代理) 实例。这样做的原因也可能是相当公平的,因为有关实例构造的所有细微差别只有容器本身知道,并且像不同的“激活策略”这样的“扩展”是有意与这样的方面分开的。输出为(单行,单实例):
I do not think Remo's answer is exactly to the point. It does not looks like that it "how proxies" work. If we were to use Castle directly with a simple code below it's obvious that child class is being created that inherits the user class and there is no actually need for the second instance.
So, two instances seems to be the end effect of Ninject's interception design for the reasons that are unknown to me.Two instances for Ninject interception looks like the end result of the Ninject design where Proxies Generator is actually an "activation strategy" (
Ninject.Activation.Strategies.ActivationStrategy
) that works after the fact of instance creation, so it kind of has no other choice, but to create another (proxy) instance. The reasons for that could be quite fair as well, as all the nuances about construction of instances are only known to the container itself and such "extensions" like different "activation strategies" are intentionally separated from such an aspect.The output is (single line, single instance):