问题
I have a PriorityQueue that takes a Func as construction parameter.
public PriorityQueue(ISomeOtherInjectedThing other, Func<T, T, bool> cmp_func) {...}
I bound this using Ninject:
Bind(typeof (IPriorityQueue<,>)).To(typeof(PriorityQueue<,>));
We had a weird bug in code and as part of this, we noticed that Ninject seems to generate an object Func and injects this into our priority queue, but we don't have a binding for this. The factory should have thrown an activtion exception, since we didn't pass the required comparison func. It didn't, and if I debug, I find this:
Ninject.dll!Ninject.KernelBase.Resolve.AnonymousMethod__c(Ninject.Planning.Bindings.IBinding binding) Line 386 + 0x5a bytes C#
How can I get Ninject to throw an exception as expected instead of silently generating a Func<> to inject?
回答1:
The Func-Auto binding to Func-Factory is a feature of Ninject.Extensions.Factory. See source: FuncModule.cs
If you create a specific binding for Func<T, T>
it will still override the generic binding created by FuncModule
. But as you noticed, there won't be any exceptions if you don't create that specific binding.
The simplest way to get rid of the default (open) binding is getting rid of the Factory extension.
But that is probably a bit drastic. What you can also do instead, is disabling Auto-Extension loading:
var kernel = new StandardKernel(new NinjectSettings {LoadExtensions = false});
Then you'll have to load extensions dynamically - this is done by loading their NinjectModule
implementations. For example:
IKernel.Load<FuncModule>();
Of course the FuncModule
you don't want to load, we're doing all this to get rid of it. But you'll have to do it for all the other extension modules you actually want.
Finally you'll have to create all Factory extension bindings that you need:
if (!this.Kernel.GetBindings(typeof(Func<IContext, IResolutionRoot>)).Any())
{
this.Bind<Func<IContext, IResolutionRoot>>().ToMethod(ctx => context => context.Kernel);
}
this.Bind<FuncProvider>().ToSelf().InSingletonScope();
this.Bind<IFunctionFactory>().To<FunctionFactory>();
this.Bind<IInstanceProvider>().To<StandardInstanceProvider>();
#if !SILVERLIGHT_20 && !WINDOWS_PHONE && !NETCF_35
this.Bind<IInterceptor>().To<FactoryInterceptor>()
.When(request => typeof(IFactoryProxy).IsAssignableFrom(request.Target.Member.ReflectedType));
#endif
Note:
If you are actually using the Func-Factories, i would recommend "ignoring" the issue. You now know where to look, should the issue ever arise again.
If this is an isolated problem, you could also replace your Func<,>
by an interface, making things more explicit (clean code).
Of course this is not a perfect solution by any means. It's just one of the tough choices one has to make ;-)
来源:https://stackoverflow.com/questions/24862138/stop-ninject-from-binding-funct-t-bool-automatically