我有一个 PriorityQueue,它采用 Func 作为构造参数。
public PriorityQueue(ISomeOtherInjectedThing other, Func<T, T, bool> cmp_func) {...}
我使用 Ninject 绑定(bind)它:
Bind(typeof (IPriorityQueue<,>)).To(typeof(PriorityQueue<,>));
我们在代码中遇到了一个奇怪的错误,作为其中的一部分,我们注意到 Ninject 似乎生成了一个对象 Func 并将其注入(inject)到我们的优先级队列中,但我们没有对此进行绑定(bind)。工厂应该抛出一个事件异常,因为我们没有传递所需的比较函数。它没有,如果我调试,我会发现这个:
Ninject.dll!Ninject.KernelBase.Resolve.AnonymousMethod__c(Ninject.Planning.Bindings.IBinding binding) Line 386 + 0x5a bytes C#
如何让 Ninject 按预期抛出异常,而不是默默生成 Func<> 来注入(inject)?
最佳答案
Func-Auto 与 Func-Factory 的绑定(bind)是 Ninject.Extensions.Factory 的一项功能。参见来源: FuncModule.cs
如果您为 Func<T, T>
创建特定绑定(bind)它仍然会覆盖 FuncModule
创建的通用绑定(bind)。但正如您所注意到的,如果您不创建该特定绑定(bind),则不会有任何异常(exception)。
摆脱默认(开放)绑定(bind)的最简单方法是摆脱 Factory 扩展。
但这可能有点极端。您还可以做的是禁用 Auto-Extension loading :
var kernel = new StandardKernel(new NinjectSettings {LoadExtensions = false});
然后您必须动态加载扩展 - 这是通过加载它们的 NinjectModule
来完成的实现。例如:
IKernel.Load<FuncModule>();
当然是FuncModule
你不想加载,我们正在做这一切来摆脱它。但是您必须为您真正想要的所有其他扩展模块执行此操作。
最后,您必须创建所需的所有工厂扩展绑定(bind):
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
注意:
如果您实际上正在使用 Func-Factories,我建议“忽略”该问题。如果问题再次出现,您现在知道该去哪里查找。
如果这是一个孤立的问题,您也可以更换您的 Func<,>
通过接口(interface),使事情更加明确(干净的代码)。
当然,无论如何这都不是一个完美的解决方案。这只是人们必须做出的艰难选择之一;-)
关于c# - 阻止 Ninject 自动绑定(bind) Func<T, T, bool>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24862138/