我们有三个界面:IFoo
,IBar
,IBaz
。我还有各自的实现类Foo
,Bar
和Baz
。
在实现中,每个都取决于接口IContainer
。因此对于Foo
(以及Bar
和Baz
的类似情况),实现可能会显示为:
class Foo : IFoo
{
private readonly IDependency Dependency;
public Foo(IDependency dependency)
{
Dependency = dependency;
}
public void Execute()
{
Console.WriteLine("I'm using {0}", Dependency.Name);
}
}
让我们进一步说我有一个类Container
恰好包含IFoo
,IBar
和IBaz
的实例:
class Container : IContainer
{
private readonly IFoo _Foo;
private readonly IBar _Bar;
private readonly IBaz _Baz;
public Container(IFoo foo, IBar bar, IBaz baz)
{
_Foo = foo;
_Bar = bar;
_Baz = baz;
}
}
在这种情况下,我希望实现类Container
与IContainer
绑定,其约束条件是IDependency
被注入IFoo
,IBar
},IBaz
对所有三个都是一样的。以手动方式,我可以将其实现为:
IDependency dependency = new Dependency();
IFoo foo = new Foo(dependency);
IBar bar = new Bar(dependency);
IBaz baz = new Baz(dependency);
IContainer container = new Container(foo, bar, baz);
我如何在Ninject中实现这一目标?
注意:我不是在询问如何进行嵌套依赖。我的问题是如何保证物化服务中对象集合中给定的依赖关系是相同的。
为了非常明确,我理解Ninject在其标准格式中将生成与以下内容等效的代码:
IContainer container = new Container(new Foo(new Dependency()), new Bar(new Dependency()), new Baz(new Dependency()));
我不喜欢这种行为。我不能将Dependency
创建为单身人士。具体来说,这意味着如果我有多个GetService<IContainer>
请求,Ninject调用应该在语义上等同于以下手动注入:
var dep1 = new Dependency();
var container1 = new IContainer(new Foo(dep1), new Bar(dep1), new Baz(dep1));
var dep2 = new Dependency();
var container2 = new IContainer(new Foo(dep2), new Bar(dep2), new Baz(dep2));
答案 0 :(得分:3)
使用ToConstant
方法指定要绑定的确切实例。如果有机会,您可以使用Unbind
重新绑定到另一个实例:
IKernel nKernel = new StandardKernel();
nKernel.Bind<IFoo>().To<Foo>();
nKernel.Bind<IBar>().To<Bar>();
nKernel.Bind<IBaz>().To<Baz>();
nKernel.Bind<IContainer>().To<Container>();
nKernel.Bind<IDependency>().ToConstant(new Dependency());
Container c = nKernel.Get<Container>();
//utilize the container...
nKernel.Unbind<IDependency>();
nKernel.Bind<IDependency>().ToConstant(new Dependency());
c = nKernel.Get<Container>();
//utilize the container...
答案 1 :(得分:1)
编辑:
这个怎么样?
kernel.Bind<IContainer>().ToMethod(context =>
{
IDependency dependency = new Dep();
IFoo foo = new Foo(dependency);
IBar bar = new Bar(dependency);
IBaz baz = new Baz(dependency);
return new Container(foo, bar, baz);
});
答案 2 :(得分:1)
这是另一次尝试:
public class Container : IContainer
{
private IFoo _foo;
private IBar _bar;
private IBaz _baz;
public Container(IContainerDependencies dependencies)
{
_foo = dependencies.Foo;
_bar = dependencies.Bar;
_baz = dependencies.Baz;
}
}
public class ContainerDependencies : IContainerDependencies
{
public ContainerDependencies(IFoo foo, IBar bar, IBaz baz)
{
Foo = foo;
Bar = bar;
Baz = baz;
}
public IFoo Foo { get; set; }
public IBar Bar { get; set; }
public IBaz Baz { get; set; }
}
public interface IContainerDependencies
{
IFoo Foo { get; set; }
IBar Bar { get; set; }
IBaz Baz { get; set; }
}
然后:
var kernel = new StandardKernel();
kernel.Bind<IFoo>().To<Foo>();
kernel.Bind<IBar>().To<Bar>();
kernel.Bind<IBaz>().To<Baz>();
kernel.Bind<IContainerDependencies>().ToMethod(context =>
{
context.Kernel.Unbind<IDependency>();
context.Kernel.Bind<IDependency>().ToConstant(new Dep());
return context.Kernel.Get<ContainerDependencies>();
});
kernel.Bind<IContainer>().To<Container>();