1

Я думаю, что мне не хватает ключевой части того, как на самом деле использовать IoC/DI. Я использую контейнер Unity. Я знаю, как настроить класс, чтобы его вложения были введены, и я также знаю, как сделать Unity зарегистрированным типом.Ioc/DI - Как использовать зарегистрированные зависимости?

Но я не знаю, как на самом деле воспользоваться этими регистрациями.

Так, например:

var container = new UnityContainer(); 
container.RegisterType<IRepository, XmlRepository>(); 

var service = new MyService(container.Resolve<IRepository>()); 

public interface IRepository 
{ 
    void GetStuff(); 
} 

public class XmlRepository : IRepository 
{ 
    public void GetStuff() 
    { 
     throw new NotImplementedException(); 
    } 
} 

public class MyService 
{ 
    private readonly IRepository _myRepository; 
    public MyService(IRepository repository) 
    { 
     _myRepository = repository; 
    } 
} 

Здесь у меня есть слой служб, который принимает параметр типа IRepository. Это контейнер часть, что я, кажется, не понимаю.

  • Нельзя ли IoC/DI не иметь возможности вручную разрешать типы каждый раз, когда мне нужно создать экземпляр? В моем коде я получаю контейнер для разрешения типа, если я не понимаю, как это должно работать, разве контейнер не должен как-то автоматически (с отражением?) Вводить зависимость, которую я сказал ей использовать, когда я зарегистрирован тип? var service = new MyService(...) Правильно ли это делает container.Resolve?
  • Я создал контейнер, но как мне поделиться этим контейнером среди моего проекта/кода? Это относится к первому вопросу. Раньше я думал, что существует одно место, в котором вы регистрируете типы. До сих пор единственным способом я могу видеть, как обойти эту проблему заключается в следующем:
    • Keep регистрации типов, где я использую их и в конечном итоге с дублированного кода
    • Пропустите контейнер вокруг каждого места, я собираюсь быть разрешающие типы
    • Ни один из этих способов являются, как я бы ожидать, чтобы это работало
+2

Если IoC правильно настроена, служба * only *, которая должна быть разрешена вручную, является «root» (их может быть несколько). В этом случае корнем является MyService, а не IRespository. Таким образом, после регистрации MyService и IRepository, 'var service = container.Resolve ();' - и контейнер IoC автоматически разрешит зависимость IRepository. (Unity также автоматически разрешает незарегистрированные типы бетона, поэтому даже не нужно регистрировать MyService.) – user2864740

+0

Связано: http://stackoverflow.com/q/9501604/126014 –

+0

Связано: http://stackoverflow.com/ q/2386487/126014 –

ответ

5

Нельзя ли IoC/DI не иметь возможности вручную разрешать типы каждый раз, когда мне нужно создать экземпляр?

Нет, это точка DI контейнер, но есть недостатки использования контейнера, а также. Положите Pure DI на использование контейнера DI, так как это научит вас использовать инъекции зависимостей, используя только первые принципы.

Я создал контейнер, но как мне поделиться этим контейнером среди моего проекта/кода?

У вас нет. Контейнер DI должен использоваться только в Composition Root (если вы вообще используете контейнер DI).

+0

Это отличный ответ, идея корневой композиции была ключевой идеей, которую я пропустил, изучая это. – user9993

1

Положите вашу установку контейнера в модуле, который запускается при запуске программы. Вы можете назвать это от Main, например. Это называется загрузочным ремнем.

См. Dependency Injection with Unity для примера того, как это сделать.

1

Вам не нужно делать new MyService(container.Resolve<IRepository>()). Чтобы получить экземпляр MyService, просто используйте container.Resolve<MyService>(); он автоматически разрешит зависимости для MyService.

Смежные вопросы