views:

98

answers:

3

How do I wire up dependencies where the dependency is in the form of a collection ??

For Example:

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
}
}

How do i use a container like Ninject in a case like this ??

EDIT: I am not talking specifically about Ninject but thats the DI/IOC I use the most. :)

A: 

I don't know about Ninject. in Castle Windsor, you'd use ListResolver and that would provide all implementations of IShuriken.

Krzysztof Koźmic
+1  A: 

In Autofac you'd use an IEnumerable constructor dependency:

public class Ninja {

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

Autofac will find any available shurikens and provide them to the constructor automatically.

Nicholas Blumhardt
+1  A: 

You can Bind a closed type List<X> ToConstant(), ToMethod() etc.

But you'd have to supply more detail as to what you want in the list or I'd just be engaging in idle speculation as to exactly what you want.

EDIT in response to yours and your comment: If you're dealing with 'Unknown' or loose dependencies, then MEF does lots of stuff in that direction.

[In general with DI] If you're doing something internally and it's a more 'Known' / fixed / complex resolution mechanism, you're better off modelling something like this by having a Repository or other coordinating object that will manage the list that you can request subsets and/or other projections of on an as-needed basis.

[If you're interested in specific mechanisms in Niject] You'd be crazy not to download the source and do a grep/FIF/Shift-Ctrl-Q for List to find out the real story though - the code is clean and neat and the Tests provide examples.

For example, you can Bind multiple items to an interface and then have them added into a collection for you automatically:-

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; }
}

}

Ruben Bartelink
+1 you have given me a good starting point. The real problem is a bit more complex than what I have in the question and I wasnt able to come up with a better sample..i will update the question if I can think of one :)
Perpetualcoder