如何在Collection表单中注入依赖项?

时间:2010-04-22 06:46:21

标签: dependency-injection inversion-of-control ninject

如何以依赖集合的形式连接依赖项?

例如:

public class Ninja {

public List<IShuriken> Shurikens {get;set;}
public IKatana Katana {get;set;}

public void Attack()
{
  // some code goes here to use weapons and kill people
}
}

在这种情况下如何使用像Ninject这样的容器?

编辑:我不是特别谈论Ninject,但那是我使用最多的DI / IOC。 :)

3 个答案:

答案 0 :(得分:1)

在Autofac中,您将使用IEnumerable构造函数依赖项:

public class Ninja {

  public Ninja(IEnumerable<IShuriken> shurikens, IKatana katana)
  {
    // ...
  }

Autofac会找到任何可用的shurikens并自动将它们提供给构造函数。

答案 1 :(得分:1)

您可Bind关闭类型List<X> ToConstant()ToMethod()等。

但你必须在列表中提供更多关于你想要的细节,或者我只是在闲置猜测你想要什么。

编辑以回应你和你的评论:如果你正在处理'未知'或松散的依赖关系,那么MEF会朝那个方向做很多事情。

[一般用DI]如果你在内部做一些事情并且它是一个更“已知”/固定/复杂的解决机制,你最好通过拥有一个将要管理的存储库或其他协调对象来建模这样的东西您可以根据需要请求子集和/或其他预测的列表。

[如果你对Niject中的特定机制感兴趣]你不要为download the source而疯狂,并为List做一个grep / FIF / Shift-Ctrl-Q来找出真实的虽然故事 - 代码干净整洁,测试提供了例子。

例如,您可以将多个项目绑定到界面,然后将它们自动添加到集合中: -

namespace Ninject.Tests.Integration.EnumerableDependenciesTests {
public class WhenServiceRequestsUnconstrainedListOfDependencies 
{
    [Fact]
    public void ServiceIsInjectedWithListOfAllAvailableDependencies()
    {
        kernel.Bind<IParent>().To<RequestsList>();
        kernel.Bind<IChild>().To<ChildA>();
        kernel.Bind<IChild>().To<ChildB>();

        var parent = kernel.Get<IParent>();

        VerifyInjection( parent );
    }

    protected override void VerifyInjection( IParent parent )
    {
        parent.ShouldNotBeNull();
        parent.Children.ShouldNotBeNull();
        parent.Children.Count.ShouldBe( 2 );
        parent.Children[0].ShouldBeInstanceOf<ChildA>();
        parent.Children[1].ShouldBeInstanceOf<ChildB>();
    }
}

public class RequestsList : IParent
{
    public IList<IChild> Children { get; private set; }

    public RequestsList( List<IChild> children )
    {
        Children = children;
    }
}

public interface IChild { }

public class ChildA : IChild { }
public class ChildB : IChild { }

public interface IParent
{
    IList<IChild> Children { get; }
}

}

答案 2 :(得分:0)

我不知道Ninject。在Castle Windsor中,您将使用ListResolver,这将提供IShuriken的所有实现。