通过名称绑定 ninject
Binding ninject via name
我有一个 ninject 问题,我在多种类型上使用相同的接口来为我的应用程序提供配置 class。
启动该应用程序的入口点 classes(下方)是从 ninject 内核返回的,我对该 class 有一个命名的 Config
依赖项。
public ProcessA(ILogger logger, [Named("TypeA")] IConfigProvider configProvider)
{
_logger = logger;
_configProvider = configProvider;
}
public ProcessB(ILogger logger, [Named("TypeB")] IConfigProvider configProvider)
{
_logger = logger;
_configProvider = configProvider;
}
然后在我的绑定中
Bind<IConfigProvider>().To<ProcessA>().Named("TypeA");
Bind<IConfigProvider>().To<ProcessB>().Named("TypeB");
在处理线的下方 ProcessA
和 ProcessB
共享一些需要 IConfigProvider
的 classes 但当 ProcessA
或 ProcessB
到了那个点 ninject 无法解决依赖关系。那时我无法将其命名为依赖项,因为两个处理器都使用 classes。
我可以将具体的 Config
class 从 ProcessA
和 ProcessB
传递下来,删除构造函数依赖性,但这似乎不是正确的方法。
编辑 1(来自 BatteryBackupUnit 的回答)
我删除了命名引用并添加了下面的内容,这似乎可以解决问题。在以下问题 Ninject Bind When Ancestor Of Type T 上找到了一个方法,但我必须添加对 request.Target == null
的检查,否则当我从 ProcessA
和 ProcessB
获得一个实例时它不会工作 ninject 内核.
public override void Load()
{
Bind<IConfigProvider>()
.To<TypeAConfigProvider>()
.When(request => HasAncestorOfType<ProcessA>(request));
Bind<IConfigProvider>()
.To<TypeBConfigProvider>()
.When(request => HasAncestorOfType<ProcessB>(request));
}
private static bool HasAncestorOfType<T>(IRequest request)
{
if (request == null || request.Target == null)
return false;
if (request.Target.Member.ReflectedType == typeof(T))
return true;
return HasAncestorOfType<T>(request.ParentRequest);
}
您可以使用 contextual binding 机制来实现。
有关所有可用方法,请参阅 IBindingWhenSyntax.cs。
WhenAnyAncestorNamed
怎么样?
或者,WhenInjectedInto<>
绑定可以像这样使用:
Bind<IConfigProvider>().To<ConfigA>()
.WhenInjectedInto<ProcessA>();
现在,由于您实际上并不想将其直接注入 ProcessA
,因此您必须使用 When
条件,例如 WhenInjectedIntoAncestor<Process>()
。您可以自己创建它 - 作为从 WhenAnyAncestorMatches
扩展方法扩展的扩展方法。另见 here
我有一个 ninject 问题,我在多种类型上使用相同的接口来为我的应用程序提供配置 class。
启动该应用程序的入口点 classes(下方)是从 ninject 内核返回的,我对该 class 有一个命名的 Config
依赖项。
public ProcessA(ILogger logger, [Named("TypeA")] IConfigProvider configProvider)
{
_logger = logger;
_configProvider = configProvider;
}
public ProcessB(ILogger logger, [Named("TypeB")] IConfigProvider configProvider)
{
_logger = logger;
_configProvider = configProvider;
}
然后在我的绑定中
Bind<IConfigProvider>().To<ProcessA>().Named("TypeA");
Bind<IConfigProvider>().To<ProcessB>().Named("TypeB");
在处理线的下方 ProcessA
和 ProcessB
共享一些需要 IConfigProvider
的 classes 但当 ProcessA
或 ProcessB
到了那个点 ninject 无法解决依赖关系。那时我无法将其命名为依赖项,因为两个处理器都使用 classes。
我可以将具体的 Config
class 从 ProcessA
和 ProcessB
传递下来,删除构造函数依赖性,但这似乎不是正确的方法。
编辑 1(来自 BatteryBackupUnit 的回答)
我删除了命名引用并添加了下面的内容,这似乎可以解决问题。在以下问题 Ninject Bind When Ancestor Of Type T 上找到了一个方法,但我必须添加对 request.Target == null
的检查,否则当我从 ProcessA
和 ProcessB
获得一个实例时它不会工作 ninject 内核.
public override void Load()
{
Bind<IConfigProvider>()
.To<TypeAConfigProvider>()
.When(request => HasAncestorOfType<ProcessA>(request));
Bind<IConfigProvider>()
.To<TypeBConfigProvider>()
.When(request => HasAncestorOfType<ProcessB>(request));
}
private static bool HasAncestorOfType<T>(IRequest request)
{
if (request == null || request.Target == null)
return false;
if (request.Target.Member.ReflectedType == typeof(T))
return true;
return HasAncestorOfType<T>(request.ParentRequest);
}
您可以使用 contextual binding 机制来实现。
有关所有可用方法,请参阅 IBindingWhenSyntax.cs。
WhenAnyAncestorNamed
怎么样?
或者,WhenInjectedInto<>
绑定可以像这样使用:
Bind<IConfigProvider>().To<ConfigA>()
.WhenInjectedInto<ProcessA>();
现在,由于您实际上并不想将其直接注入 ProcessA
,因此您必须使用 When
条件,例如 WhenInjectedIntoAncestor<Process>()
。您可以自己创建它 - 作为从 WhenAnyAncestorMatches
扩展方法扩展的扩展方法。另见 here