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

时间:2011-01-05 17:00:49

标签: ninject

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

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

它运行良好,但我们将有几个IObjC实现。我有什么选择可以继续将实现流体分配给IObjA / IObjB的接口,但是允许IObjC的可配置分配?

我找到了related question on SO,但我不知道我是否可以同时支持流量和可配置方法。

例如,我可以将Ninject.extensions.xml用于IObjC,同时继续对IObjA和IObjB使用上述方法吗?

是否建议为IObjC进行条件分配?这看起来很脏但同时看起来很简单。

if (condition1)
  Bind<IObjC>().To<ObjC1>().InRequestScope();
else if (condition 2)
  Bind<IObjC>().To<ObjC2>().InRequestScope();

另外,我知道像Castle这样的其他框架支持XML配置,但我想继续使用Ninject。

1 个答案:

答案 0 :(得分:5)

1 - 您对IObjC的绑定与任何其他绑定无关。无论何时,何地或如何绑定其他服务都无关紧要。

2 - 你可以使用XML扩展,但我会问为什么你认为你需要它是可配置的。

3 - 您的条件有两种可能性。首先,您要在启动时做出决定,以确定是否在应用程序或ObjC2的整个生命周期内使用ObjC1。如果是这样的话,你的代码就可以了。但是,如果要在每次解析绑定时动态决定使用哪个对象,则需要将条件放在绑定中,如下所示:

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" );