阻止Ninject自动绑定Func <t,t,=“”bool =“”> </t,>

时间:2014-07-21 09:49:11

标签: c# dependency-injection ninject func

我有一个PriorityQueue,它将Func作为构造参数。

public PriorityQueue(ISomeOtherInjectedThing other, Func<T, T, bool> cmp_func) {...}

我使用Ninject绑定了这个:

Bind(typeof (IPriorityQueue<,>)).To(typeof(PriorityQueue<,>));

我们在代码中有一个奇怪的错误,作为其中的一部分,我们注意到Ninject似乎生成一个对象Func并将其注入我们的优先级队列,但我们没有绑定。工厂应该抛出一个激活异常,因为我们没有通过所需的比较功能。它没有,如果我调试,我发现:

Ninject.dll!Ninject.KernelBase.Resolve.AnonymousMethod__c(Ninject.Planning.Bindings.IBinding binding) Line 386 + 0x5a bytes C#

如何让Ninject按预期抛出异常,而不是静默生成Func&lt;&gt;注入?

1 个答案:

答案 0 :(得分:2)

Func-Auto绑定到Func-Factory是Ninject.Extensions.Factory的一个功能。见来源: FuncModule.cs

如果为Func<T, T>创建特定绑定,它仍将覆盖FuncModule创建的通用绑定。但正如您所注意到的,如果您不创建特定的绑定,则不会有任何例外。

摆脱默认(开放)绑定的最简单方法是摆脱Factory扩展。

但这可能有点激烈。您也可以做的是禁用Auto-Extension loading

var kernel = new StandardKernel(new NinjectSettings {LoadExtensions = false});

然后,您必须动态加载扩展程序 - 这可以通过加载NinjectModule实现来完成。例如:

IKernel.Load<FuncModule>();

当然,您不想加载FuncModule,我们正在做所有这些以摆脱它。但是你必须为你真正想要的所有其他扩展模块做这件事。 最后,您必须创建所需的所有Factory扩展绑定:

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,我会建议&#34;忽略&#34;问题。如果问题再次出现,你现在知道在哪里看。 如果这是一个孤立的问题,您还可以通过接口替换Func<,>,使事情更明确(干净的代码)。 当然,这绝不是一个完美的解决方案。这只是人们必须做出的艰难抉择之一; - )