Ninject - 如何动态选择要绑定到接口的实现

3

我目前正在使用Ninject在WCF服务应用程序中创建接口的实例。

Bind<IObjA>().To<ObjA>().InRequestScope();
Bind<IObjB>().To<ObjB>().InRequestScope();
Bind<IObjC>().To<ObjC>().InRequestScope();

它的效果很好,但我们将有几个IObjC的实现。对于IObjA/IObjB接口的流畅分配,我有哪些选项,但允许IObjC的可配置分配?我在SO上找到了一个相关问题,但我不知道是否可以同时支持流畅和可配置的方法。例如,我可以在IObjA和IObjB上继续使用上述方法,同时为IObjC使用Ninject.extensions.xml吗?是否建议为IObjC进行条件分配?这似乎很糟糕,但同时看起来非常简单。
if (condition1)
  Bind<IObjC>().To<ObjC1>().InRequestScope();
else if (condition 2)
  Bind<IObjC>().To<ObjC2>().InRequestScope();

此外,我知道其他框架(如Castle)支持XML配置,但我想继续使用Ninject。
1个回答

5

1 - 您与IObjC的绑定与其他绑定无关。无论您何时、何地、以及如何绑定其他服务都没有关系。

2 - 您可以使用XML扩展,但我想问一下为什么您认为需要使其可配置。

3 - 对于您的条件语句有两种可能性。第一种是您希望在启动时做出决策,确定整个应用程序的生命周期中使用ObjC1还是ObjC2。如果是这样,您的代码是正确的。然而,如果您希望每次解析绑定时动态决定要使用哪个对象,则需要将条件放在绑定内部,如下所示:

Bind<IObjC>().ToMethod( ctx => condition ? ctx.Kernel.Get<ObjC1>() : ctx.Kernel.Get<ObjC2>() );

或者,您可以使用命名绑定:

Bind<ILog>().ToConstant( LogManager.GetLogger( "Accounting" ) ).Named( "Accounting" );

或者使用“当”条件来帮助:
Bind<ILog>().ToConstant( LogManager.GetLogger( "Background" ) ).When( context => context.Target != null && context.Target.Name == "backgroundLogger" );

1
假设您想在不同的机器上使用相同的程序(.exe),从不同的数据库或XML中读取数据(数据结构不同),因此您需要配置每种情况下要使用的DAL。您会如何处理? - Morvader
你不会只是在app.config中有不同的连接字符串吗?否则,这将是使用XML配置的好时机。 - Dave Thieben

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接