SlideShare a Scribd company logo
Dependency Injection,
        IoC
План

IoC принцип

Dependency injection

Как не стоит определять зависимости

Простой пример
Термины

Сервис - объект, который может выполняет какую-либо
требуемую функцию

Клиент - тот, кто использует сервис

Зависимость - сервис, который требуется другому объекту
для выполнения каких-либо функций

Зависимый - объект, которому нужен сервис для того,
чтобы выполнять какие-либо возложенные на него функции
IoC, истоки
public class Reporter
{
     public void SendReports()
     {
        var reportBuilder = new
ReportBuilder();
        var report =
reportBuilder.CreateReport();
        var reportSender = new
EmailReportSender();
        reportSender.Send(report);
    }
}
Что хорошего?



Это просто
Что плохого?


Это нетестируемо

Это сильное связывание, которое
приводит к монолитности OOD

В итоге это превращается в ад
Эволюция
public class Reporter
{
     public void SendReports()
     {
        var reportBuilder =
ServiceLocator.ReportBuilder;
        var report =
reportBuilder.CreateReport();
        var reportSender =
ServiceLocator.ReportSender;
        reportSender.Send(report);
    }
}
Стало лучше, но...

Мы должны поддерживать ServiceLocator

Зависимый объект всё равно
определяет свои зависимости внутри
реализации

Зависимости неочевидны
IoC approach
public class Reporter
{
     private readonly IReportBuilder _builder;
     private readonly IReportSender _sender;

      public Reporter(IReportBuilder builder,
                      IReportSender sender)
      {
         _builder = builder;
        _sender = sender;
      }
     public void SendReports()
     {
        var report = _builder.CreateReport();
        _sender.Send(report);
    }
}
IoC approach

ReportSender не может определить свои
зависимости самостоятельно

Зависимости очевидны

Тестировать проще

Слабосвязанная архитектура
DI with IoC containers

Ответсвенность за внедрение
зависимостей перекладывается на
специальный фреймворк (IoC container)

Зависимости конфигурируются в коде
или конфиг-файлах
DI with IoC containers


var reporter = container.Get<Reporter>();
reporter.SendReports();
Антипаттерны IoC

Control Freak

Bastard injection

Constrained injection

Service locator

Property injection *
Control Freak /
Диктатор-наркоман :)
       public class Reporter
       {
            public void SendReports()
            {
               var reportBuilder = new
       ReportBuilder();
               var report =
       reportBuilder.CreateReport();
               var reportSender = new
       EmailReportSender();
               reportSender.Send(report);
           }
       }
Bastard injection /
внебрачные зависимости
     public class Reporter
     {
          private readonly IReportBuilder _builder;
          private readonly IReportSender _sender;

          public Reporter(IReportBuilder builder,
                          IReportSender sender)
          {
             _builder = builder;
            _sender = sender;
          }

          public Reporter()
                 this(ReportBuilder.GetDefaultBuilder(),
                 ReportSender.GetDefaultSender())
          {
             _builder = builder;
            _sender = sender;
          }
     }
Constrained construction /
    ограниченное построение



Type bulderType = GetBuilderType();
Type senderType = GetSenderType();
Reporter reporter =
Activator.CreateInstance(typeof(Reporter)
, builderType, senderType);
Service locator
public class Reporter
{
     public void SendReports()
     {
        var reportBuilder =
ServiceLocator.Get<IReportBuilder>();
        var report =
reportBuilder.CreateReport();
        var reportSender =
ServiceLocator.Get<IReportSender>();
        reportSender.Send(report);
    }
}
Property injection *

Не антипаттерн в класическом понимании, но
требует осторожности

Используйте только тогда, когда это
дейтствительно нужно (какой-либо фреймворк
требует конструктор без параметров)

Используйте тогда, когда поведение объкта
меняется во время выполнения
Property injection *

public class Reporter
{
      public IReportBuilder Builder { get;set; }
      public IReportSender Sender { get;set; }
     public void SendReports()
     {
        var report = Builder.CreateReport();
        Sender.Send(report);
    }
}
Property injection *

Можно изменить зависимости во время
выполнения (например, при смене
настроек без перезапуска приложения)

Если забыть определить зависимости, то
получим исключение на этапе
выполнения
.NET DI/IoC frameworks

 Unity

 Ninject

 Autofac

 StructureMap

 Castle Windsor

More Related Content

PDF
CocoaHeads Moscow. Владислав Дугнист. «Dependency Injection с Blood Magic»
PPTX
сервисы в Angular js
PPTX
Разработка Web-приложений на Angular JS. Архитектурные семинары Softengi
PPTX
C language lect_22_advanced
PPS
Motivasi katak
PPTX
Wellnology 6
PPT
PPS
Para Entender El Socialismo
CocoaHeads Moscow. Владислав Дугнист. «Dependency Injection с Blood Magic»
сервисы в Angular js
Разработка Web-приложений на Angular JS. Архитектурные семинары Softengi
C language lect_22_advanced
Motivasi katak
Wellnology 6
Para Entender El Socialismo

Similar to IoC & Dependency Injection (20)

PDF
Rambler.iOS #3: Dependency Injection в iOS
PDF
Rambler.iOS #5: VIPER и Swift
PPTX
Viper - чистая архитектура iOS-приложения (И. Чирков)
PPTX
PPTX
Модульная структура. Цветцих Денис D2D Just.NET
PPTX
Модульная структура
PPT
6 создание распределенных приложений по технологии remoting
PPTX
Code Contracts ABC 16.04.2011
PPTX
Практика использования Dependency Injection
PDF
Чуть сложнее чем Singleton: аннотации, IOC, АОП
PDF
Школа-студия разработки приложений для iOS. 2 лекция. MVC, View, Controllers
PDF
GTUG Almaty. Dependency Injection в Android
PPTX
Dependency Injection на примере Unity и NInject
PPTX
Dependency injection на примере unity и n inject
PDF
Инфраструктура распределенных приложений на nodejs / Станислав Гуменюк (Rambl...
PPTX
Как приручить реактивное программирование
PDF
Чуть сложнее чем Singleton: аннотации, IOC, АОП
PDF
Курсы по мобильной разработке. 2 лекция. Построение интерфейсов в iOS
PPTX
Viper в ios проектах
Rambler.iOS #3: Dependency Injection в iOS
Rambler.iOS #5: VIPER и Swift
Viper - чистая архитектура iOS-приложения (И. Чирков)
Модульная структура. Цветцих Денис D2D Just.NET
Модульная структура
6 создание распределенных приложений по технологии remoting
Code Contracts ABC 16.04.2011
Практика использования Dependency Injection
Чуть сложнее чем Singleton: аннотации, IOC, АОП
Школа-студия разработки приложений для iOS. 2 лекция. MVC, View, Controllers
GTUG Almaty. Dependency Injection в Android
Dependency Injection на примере Unity и NInject
Dependency injection на примере unity и n inject
Инфраструктура распределенных приложений на nodejs / Станислав Гуменюк (Rambl...
Как приручить реактивное программирование
Чуть сложнее чем Singleton: аннотации, IOC, АОП
Курсы по мобильной разработке. 2 лекция. Построение интерфейсов в iOS
Viper в ios проектах
Ad

IoC & Dependency Injection

  • 2. План IoC принцип Dependency injection Как не стоит определять зависимости Простой пример
  • 3. Термины Сервис - объект, который может выполняет какую-либо требуемую функцию Клиент - тот, кто использует сервис Зависимость - сервис, который требуется другому объекту для выполнения каких-либо функций Зависимый - объект, которому нужен сервис для того, чтобы выполнять какие-либо возложенные на него функции
  • 4. IoC, истоки public class Reporter {      public void SendReports()      {         var reportBuilder = new ReportBuilder();         var report = reportBuilder.CreateReport();         var reportSender = new EmailReportSender();         reportSender.Send(report);     } }
  • 6. Что плохого? Это нетестируемо Это сильное связывание, которое приводит к монолитности OOD В итоге это превращается в ад
  • 7. Эволюция public class Reporter {      public void SendReports()      {         var reportBuilder = ServiceLocator.ReportBuilder;         var report = reportBuilder.CreateReport();         var reportSender = ServiceLocator.ReportSender;         reportSender.Send(report);     } }
  • 8. Стало лучше, но... Мы должны поддерживать ServiceLocator Зависимый объект всё равно определяет свои зависимости внутри реализации Зависимости неочевидны
  • 9. IoC approach public class Reporter { private readonly IReportBuilder _builder; private readonly IReportSender _sender; public Reporter(IReportBuilder builder, IReportSender sender) { _builder = builder; _sender = sender; }      public void SendReports()      {         var report = _builder.CreateReport();         _sender.Send(report);     } }
  • 10. IoC approach ReportSender не может определить свои зависимости самостоятельно Зависимости очевидны Тестировать проще Слабосвязанная архитектура
  • 11. DI with IoC containers Ответсвенность за внедрение зависимостей перекладывается на специальный фреймворк (IoC container) Зависимости конфигурируются в коде или конфиг-файлах
  • 12. DI with IoC containers var reporter = container.Get<Reporter>(); reporter.SendReports();
  • 13. Антипаттерны IoC Control Freak Bastard injection Constrained injection Service locator Property injection *
  • 14. Control Freak / Диктатор-наркоман :) public class Reporter {      public void SendReports()      {         var reportBuilder = new ReportBuilder();         var report = reportBuilder.CreateReport();         var reportSender = new EmailReportSender();         reportSender.Send(report);     } }
  • 15. Bastard injection / внебрачные зависимости public class Reporter { private readonly IReportBuilder _builder; private readonly IReportSender _sender; public Reporter(IReportBuilder builder, IReportSender sender) { _builder = builder; _sender = sender; } public Reporter() this(ReportBuilder.GetDefaultBuilder(), ReportSender.GetDefaultSender()) { _builder = builder; _sender = sender; } }
  • 16. Constrained construction / ограниченное построение Type bulderType = GetBuilderType(); Type senderType = GetSenderType(); Reporter reporter = Activator.CreateInstance(typeof(Reporter) , builderType, senderType);
  • 17. Service locator public class Reporter {      public void SendReports()      {         var reportBuilder = ServiceLocator.Get<IReportBuilder>();         var report = reportBuilder.CreateReport();         var reportSender = ServiceLocator.Get<IReportSender>();         reportSender.Send(report);     } }
  • 18. Property injection * Не антипаттерн в класическом понимании, но требует осторожности Используйте только тогда, когда это дейтствительно нужно (какой-либо фреймворк требует конструктор без параметров) Используйте тогда, когда поведение объкта меняется во время выполнения
  • 19. Property injection * public class Reporter { public IReportBuilder Builder { get;set; } public IReportSender Sender { get;set; }      public void SendReports()      {         var report = Builder.CreateReport();         Sender.Send(report);     } }
  • 20. Property injection * Можно изменить зависимости во время выполнения (например, при смене настроек без перезапуска приложения) Если забыть определить зависимости, то получим исключение на этапе выполнения
  • 21. .NET DI/IoC frameworks Unity Ninject Autofac StructureMap Castle Windsor