Ninject Interception extension is creating 2 instances of the class; is there a way to avoid this
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().Intercep开发者_StackOverflow社区t().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 :) ).
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.
class A{ }
class AProxy : A {}
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.
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.
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();
}
}
The output is (single line, single instance):
ctor for Castle.Proxies.TestProxy base is UserQuery+Test
精彩评论