如何在Ninject中进行适当的上下文绑定?

时间:2019-02-15 21:40:42

标签: inversion-of-control ninject unity-container castle-windsor

到目前为止,我已经设法使用Unity和Castle Windsor轻松实现上下文绑定。意思是,给定一个接口的多个注册实现,我可以注册使用客户端组件作为依赖来选择特定组件的客户端组件。但是对于Ninject,执行此操作和我在以下示例中发现的界面似乎并不相同:

https://github.com/ninject/Ninject/wiki/Contextual-Binding#simple-constrained-resolution-named-bindings

团结示例:

给出接口,IFoo和实现Foo1,Foo2,Foo3。

container.RegisterType<IFoo , Foo1>("Foo1", new TransientLifetimeManager());
container.RegisterType<IFoo , Foo2>("Foo2", new TransientLifetimeManager());
container.RegisterType<IFoo , Foo3>("Foo3", new TransientLifetimeManager());
container.RegisterType<FooClient, FooClient>("FooClient1", new InjectionConstructor(new ResolvedParameter<IFoo>("Foo2")));
var fooClient = container.Resolve<FooClient>("FooClient1");

温莎城堡示例:

internal class FooInstaller: IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container.Register(Component.For<IFoo>().Named("Foo1").ImplementedBy<Foo1>().LifeStyle.Transient);
        container.Register(Component.For<IFoo>().Named("Foo2").ImplementedBy<Foo2>().LifeStyle.Transient);
        container.Register(Component.For<IFoo>().Named("Foo3").ImplementedBy<Foo3>().LifeStyle.Transient);
        container.Register(Component.For<FooClient>().LifeStyle.Singleton.DependsOn(ServiceOverride.ForKey<IFoo>().Eq("Foo2")));
    }
}
var fooClient = container.Resolve<FooClient>();

注入(使用绑定元数据):

class FooClient{
    public FooClient(Named["Foo2"] IFoo fooDependency)
    {
    }
    ....
}
通过直接使用服务定位器而不是依靠自动解析来要求特定的实现,甚至在文档中也承认

是一种反模式。

Unity&Castle Windsor完全按预期工作,fooClient使用了IFoo的Foo2实现。它已自动解决。

关于Ninject方法,这种方法行得通,但这意味着它很难融入更高级别组件的实现中,而且我违反了依赖反转原则。关于Unity / Windsor方法的一个好地方是组成根(IOC设置)是隔离点。

我错过了Ninject API上的某些东西,可以保留DIP吗?

1 个答案:

答案 0 :(得分:0)

条件绑定

您可以使用:

Bind<FooClient>().ToSelf();
Bind<IFoo>().To<Foo2>().WhenInjectedInto<FooClient>();

绑定参数

Bind<Foo2>().ToSelf();

Bind<FooClient>().ToSelf()
    .WithConstructorArgument(typeof(IFoo)), ctx => ctx.Kernel.Get<Foo2>());

注意:当然,您也可以解决Kernel.Get<IFoo>("foo2")。 注意:键入“来自内存”,可能无法编译,因为语法可能略有不同。

相关问题