I'm trying to understand how Ninject.Extensions.Interception 3.0.0.8 is building dynamic proxies for my classes. I've found that when I decorate my concrete classes with an attribute that inherits from InterceptAttribute or when I directly Intercept at binding time with Intercept() method then Ninject returns a Dynamic Proxy of the decorated class instead of the normal type.
I have a IPolicySearchPresenter interface which I'm binding to FlexPolicySearchPresenter concrete type adding an Exception logger interceptor:
Bind<IExceptionInterceptor>().To<ExceptionInterceptor>();
Bind<IPolicySearchPresenter>().To<FlexPolicySearchPresenter>().Intercept().With<IExceptionInterceptor>();
The problem is that when I inspect the returning type for that binding:
var proxy = Kernel.Get<IPolicySearchPresenter>();
I get an instance of Castle.Proxies.IPolicySearchPresenterProxy instead of FlexPolicySearchPresenterProxy
This is giving me problems with my FluorineFx remoting app. However, if I create my Castle Proxy manually:
ProxyGenerator generator = new ProxyGenerator();
//My presenter type
Type type = typeof(FlexPolicySearchPresenter);
//My presenter interface
var interfaceType = type.GetInterfaces().Single();
//Get my Interceptor from container. Notice that i had to
//change my Interceptor to implement IInterceptor from Castle libs,
// instead of Ninject IInterceptor
var excepInt = Kernel.Get<ExceptionInterceptor>();
//Manually get all my instances required by my presenter type Constructor
//ideally passed through Constructor Injection
var presenterSearchService = Kernel.Get<IPolicySearchService>();
var userAuthService = Kernel.Get<IUserAuthorizationService>();
//Create proxy, passing interceptor(s) and constructor arguments
var proxy = generator.CreateClassProxy(type, new object[] { presenterSearchService, userAuthService },
new IInterceptor[]
{
excepInt
});
//Ninject.Extensions.Interception.DynamicProxyModule
// I'm using directive ToConstant(..), and not To(..)
//Bind my interface to the new proxy
Bind(interfaceType).ToConstant(proxy).InThreadScope();
var proxy = Kernel.Get<IPolicySearchPresenter>();
The returning types come back as Castle.Proxies.FlexPolicySearchPresenterProxy which work perfectly with my remoting implementation.
The question is, how can I get Ninject.Interception return me instances of FlexPolicySearchPresenterProxy instead of IPolicySearchPresenterProxy.
Notice that by doing the manual Castle way I am binding in a different way:
Bind(interfaceType).ToConstant(proxy).InThreadScope();
Instead of the ninject way:
Bind<IPolicySearchPresenter>().To<FlexPolicySearchPresenter>().Intercept().With<IExceptionInterceptor>();
Do I need to change the way I'm doing the Binding in Ninject to get the right type?
Edit: added property injection to Foo.
I've got a working solution for you, but to be honest, i'm not 100% happy about it. Anyway, this works:
The resulting output is:
And the type is:
It seems that .Bind().To() and .Bind().ToSelf().Intercept... do not have the same result. I don't know why (yet) - but maybe i'm going to investigate it.
Update on constructor arguments: Ninject by itself only supports "inheritance based class proxy" - where the class needs a default / empty ctor and "interface proxy without target" - which is what you don't want.
Therefore, would it be acceptable for you to use property injection "just this once"? Otherwise you will need to create your own interception ninject-magic and use "class proxy with target" (see http://docs.castleproject.org/Tools.Kinds-of-proxy-objects.ashx) Remark: Even though "class proxy with target" supports constructor arguments you need to know which they are beforehand (so no easy DI support). (I did not find a hook for resolving constructor arguments after dynamic proxy chooses/creates the constructor for the proxy.)