Как внедрить зависимости в форму Collection? - PullRequest
2 голосов
/ 22 апреля 2010

Как связать зависимости, где зависимость находится в форме коллекции ??

Например:

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 ]

1 голос
/ 22 апреля 2010

В Autofac вы будете использовать зависимость конструктора IEnumerable:

public class Ninja {

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

Autofac найдет любые доступные сюрикены и автоматически предоставит их конструктору.

1 голос
/ 22 апреля 2010

Вы можете Bind закрытый тип List<X> ToConstant(), ToMethod() и т. Д.

Но вам придется предоставить более подробную информацию о том, что вы хотите в списке, или я быпросто будьте вовлечены в пустые спекуляции относительно того, что именно вы хотите.

РЕДАКТИРОВАТЬ в ответ на ваши и ваш комментарий: если вы имеете дело с «Неизвестными» или свободными зависимостями, то MEF много вещей в этом направлении.

[В общем, с DI] Если вы делаете что-то внутренне, и это более «известный» / фиксированный / сложный механизм разрешения, вам лучше смоделировать что-то подобное с помощьюналичие репозитория или другого координирующего объекта, который будет управлять списком, к которому вы можете запрашивать подмножества и / или другие проекции по мере необходимости.

[Если вас интересуют конкретные механизмы в Niject] Вы 'Не спешите загрузить исходный код и выполнить grep / FIF / Shift-Ctrl-Q для List, чтобы узнать реальную историю - код чистый и аккуратный, и тесты предоставляют примеры.

ФоНапример, вы можете привязать несколько элементов к интерфейсу, а затем автоматически добавить их в коллекцию: -

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

}

0 голосов
/ 22 апреля 2010

Я не знаю о Ninject. в Castle Windsor вы будете использовать ListResolver, и это обеспечит все реализации IShuriken.

...