4

让我们有三个接口:IFoo, IBar, IBaz. 我也有类Foo, Bar, ,Baz它们是各自的实现。

在实现中,每个都依赖于接口IContainer。因此,对于Foo(以及类似地对于Barand 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绑定,并且对所有三个都相同。以手动方式,我可以将其实现为:IContainerIDependencyIFooIBarIBaz

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

3 回答 3

3

Use ToConstant method to specify exact instance to bind to. If there is an opportunity you can use Unbind to rebind to another instance:

        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...
于 2012-09-12T03:18:14.870 回答
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);
            });
于 2012-09-12T03:40:21.037 回答
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>();
于 2012-09-12T04:50:52.057 回答