停止绑定Func自动

本文关键字:bool 自动 绑定 Func | 更新日期: 2023-09-27 18:13:55

我有一个PriorityQueue,它以一个函数作为构造参数。

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

我使用Ninject:

将其绑定
Bind(typeof (IPriorityQueue<,>)).To(typeof(PriorityQueue<,>));

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

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

我怎么能让Ninject抛出一个异常,而不是无声地生成一个Func<>注入?

停止绑定Func<T, T, bool>自动

将func_auto绑定到func_factory是Ninject.Extensions.Factory的一个特性。看到来源:FuncModule.cs

如果你为Func<T, T>创建一个特定的绑定,它仍然会覆盖FuncModule创建的通用绑定。但是正如您所注意到的,如果您不创建特定的绑定,将不会有任何异常。

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

但这可能有点激烈。你也可以禁用自动扩展加载:

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

然后你必须动态加载扩展-这是通过加载它们的NinjectModule实现来完成的。例如:

IKernel.Load<FuncModule>();

当然你不想加载FuncModule,我们所做的一切都是为了摆脱它。但是对于您实际需要的所有其他扩展模块,您必须这样做。最后,您必须创建所需的所有工厂扩展绑定:

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<,>,使事情更显式(干净的代码)。当然,这无论如何都不是一个完美的解决方案。这只是一个人必须做出的艰难选择之一;-)