Ninject - как вводить при жизни объекта? - PullRequest
1 голос
/ 30 августа 2010

Я только начинаю с внедрения зависимости. Я прочитал вики Ninject, и в ней очень ясно, как внедрить зависимости, где требуется один экземпляр зависимости, с использованием конструктора, свойства или внедрения метода. Но как вы справляетесь со случаем, когда вашему классу нужно создавать объекты в течение его жизненного цикла (после создания)? Например:

class AddressBook
{
    private List<IContact> _contacts;

    public AddContact(string name)
    {
        _contacts.Add(****what?****)
    }
}

Единственный способ, которым я могу думать, - это использовать инжекцию конструктора для передачи в IKernel и использовать это для получения нашего IContact:

class AddressBook
{
    private IKernel _kernel;
    private List<IContact> _contacts;

    public AddressBook(IKernel kernel){ _kernel = kernel; }        

    public AddContact(string name)
    {
        _contacts.Add(_kernel.Get<IContact>(new Parameter("name", name)));
    }
}

Но тогда как вы на самом деле можете внедрить ядро? Какое отображение потребуется? Это даже правильный подход?

Спасибо за любую помощь Феликс

Ответы [ 3 ]

2 голосов
/ 01 сентября 2010

Подобно тому, что ответили другие, мы используем общий интерфейс IFactory:

public interface IFactory<T> 
{
    T Get();
}

, который можно использовать так:

public AddressBook(IFactory<IContact> ContactFactory)

И затем реализовать так:

public class InjectorFactory : IFactory<T> 
{
    // we wrapped the Kernel in an Injector class
    public T Get() { return Injector.Get<T>(); } 
}

И связаны так:

Bind(typeof(IFactory<>)).To(typeof(InjectorFactory<>))

До сих пор это очень хорошо сработало.

1 голос
/ 30 августа 2010

Ответ, предложенный Бенджамином Подсзуном:

Инъекция фабрики:

public interface IContactFactory
{
    IContact CreateContact(string name);
}

class AddressBook
{
    private IContactFactory _factory;
    private List<IContact> _contacts;

    public AddressBook(IContactFactory factory){ _factory = factory; }        

    public AddContact(string name)
    {
        _contacts.Add(_factory.CreateContact(name));
    }
}

Затем вы можете связать фабрику с любым, что вы хотите, для создания любого конкретного экземпляра IContact.

0 голосов
/ 01 сентября 2010

Вы можете сделать это довольно чисто с помощью: ( exec резюме другого ответа относительно немного другого вопроса )

Bind<Func<IContact>>().ToMethod( context => () => Kernel.Get<Contact>() );

Другие ваши варианты:

  • имеют IKernel инъекцию, как вы сделали (это поддерживает OOTB с любыми специальными приемами), но, как вы намекаете, это редко то, что вы хотите - это равносильно размещению службы.1013 *

    У полномасштабного завода.См. Другой ответ о идиоматическом подходе Ninject (провайдера), чтобы сделать более или менее то, что говорит ваш ответ самому себе.Вам лучше иметь вескую причину, чтобы сделать такое количество котельной плиты.

...