在其他DI容器中,我观察到了TryAddScoped,TryAddTransient,TryAddSingleton等。
Try背后的想法是避免多次注册。如果已经注册了服务,那么我想使用Try不会尝试再次注册。
使用注入
Kernel.Bind<IHttpContextAccessor>().To<HttpContextAccessor>().InSingletonScope();
那么Ninject中是否有任何Try等效项?
答案 0 :(得分:3)
没有简单的等效项。
执行
Kernel.Bind<IHttpContextAccessor>().To<HttpContextAccessor>().InSingletonScope();
Kernel.Bind<IHttpContextAccessor>().To<HttpContextAccessor>().InSingletonScope();
解析IHttpContextAccessor
时将导致异常,解析IEnumerable<IHttpContextAccessor>
时将返回两个HttpContextAccessor
实例。
但是,您可以编写自己的“尝试”:
if(!Kernel.GetBindings(typeof(IHttpContextAccessor)).Any())
{
Kernel.Bind<IHttpContextAccessor>().To<HttpContextAccessor>().InSingletonScope();
}
当然,您也可以为此编写自己的扩展方法:
public static class NinjectBindingExtensions
{
public static void TryBind<T>(
this IKernel kernel,
Action<IBindingToSyntax<T>> configureBinding)
{
if (!kernel.GetBindings(typeof(T)).Any())
{
configureBinding(kernel.Bind<T>());
}
}
}
解决此问题的一种方法是使用.Rebind
而不是.Bind
。如果没有预先存在的绑定,它将像.Bind
一样工作。如果存在预先存在的绑定,它将替换它。因此:
Kernel.Rebind<IHttpContextAccessor>().To<HttpContextAccessor>().InSingletonScope();
Kernel.Rebind<IHttpContextAccessor>().To<HttpContextAccessor>().InSingletonScope();
解析IHttpContextAccessor
将产生HttpContextAccessor
的一个实例。
如果问题不是多个组件/ NinjectModule
为同一类型创建绑定,而是两次加载相同的NinjectModule
,则可以通过以下方式防止重复加载:
if(!Kernel.HasModule(typeof(MyModule)))
{
Kernel.Load<MyModule>();
}