Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Dependency Injection на примере Unity и nInject<br />Калита Роман<br />TaskManagementSoft<br />
План<br />Что такое Dependency Injection?<br />Как проблемы решает и какие преимущества дает при проектировании<br />Какие...
Качественный код/система<br />Код<br />
Некоторые проблемы при проектировании приложений<br />По версии GoF<br />
Сильносвязанные системы<br />
Сильносвязанные системы<br />сложно<br />О каких качествах кода может идти речь?<br />
Уменьшаем связанность<br />
Фабрика, Локатор, Метод<br />Запрашивает IMyInterface<br />Клиент<br />Фабрика, Локатор, Метод<br />Создает MyClass<br />M...
Dependency Injection<br />Обявляет зависимости<br />запрашивает<br />Клиент<br />DI контейнер<br />внедряет<br />создает/в...
Что такое Dependency Injection?<br />Инверсия зависимостей == Обращение контроля == Внедрение зависимостей == Dependency i...
Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций.</li></ul>Цель:<br /><ul><li>Уменьшить связ...
Пример связанного приложения<br />publicclassOrderManager<br />{<br />publicvoid ProcessOrders()<br />        {<br />var o...
Пример связанного приложения<br />publicclassOrderManager<br />    {<br />publicvoid ProcessOrders()<br />        {<br />v...
Проблемы в примере<br /><ul><li>Тестируемость</li></ul>[TestClass]<br />publicclassOrderManagerTests<br />    {<br />     ...
Применяем используя контейнер<br />publicclassOrderManager<br />{<br />        [Inject]<br />publicIOrdersQueueordersQueue...
Ручное DI vsКонтейнер<br /><ul><li>Оба варианта решают проблему класса с высокой связанностью
Если вручную, выполнение лишней работы по созданию и наполнению зависимостями
Если используюя контейнер досутпны возможности по «автоматическому» или «условному» наполнению зависимостями, не требующие...
Время жизни объектов также должно гибко контролироватся, вручную – «лишняя работа»</li></li></ul><li>Формы Dependecy Injec...
Dependecy Injectionконтейнеры<br /><ul><li>StructureMap (AltDotNet)</li></ul>http://structuremap.sourceforge.net/Default.h...
Dependecy Injection используя Unity<br /><ul><li>Необходимо определить конфигурацию</li></ul>varunityContainer = newUnityC...
“Продвинутая” конфигурация<br /><ul><li>Условный биндинг</li></ul>Bind<IOrdersProcessor>().To<ManualOrdersProcessor>().Whe...
Преимущества от использования Dependecy Injection<br /><ul><li>Разделение конфигурирования связей и использования объектов
Уменьшается связывание</li></ul>Абстрактные интерфейсы не меняются<br />Конкретные объекты реализуют эти интерфейсы<br />К...
Улучшение изоляции объектов</li></ul>Уменьшается связность<br />Увеличивается тестируемость<br />Увеличивается удобство в ...
Ссылки<br /><ul><li>http://martinfowler.com/articles/injection.html
Upcoming SlideShare
Loading in …5
×

Dependency injection на примере unity и n inject

2,666 views

Published on

Published in: Education
  • Be the first to comment

Dependency injection на примере unity и n inject

  1. 1. Dependency Injection на примере Unity и nInject<br />Калита Роман<br />TaskManagementSoft<br />
  2. 2. План<br />Что такое Dependency Injection?<br />Как проблемы решает и какие преимущества дает при проектировании<br />Какие есть формы DI<br />DI контейнеры в .NET<br />
  3. 3. Качественный код/система<br />Код<br />
  4. 4. Некоторые проблемы при проектировании приложений<br />По версии GoF<br />
  5. 5. Сильносвязанные системы<br />
  6. 6. Сильносвязанные системы<br />сложно<br />О каких качествах кода может идти речь?<br />
  7. 7. Уменьшаем связанность<br />
  8. 8. Фабрика, Локатор, Метод<br />Запрашивает IMyInterface<br />Клиент<br />Фабрика, Локатор, Метод<br />Создает MyClass<br />MyClass<br />IMyInterface<br />Реализует IMyInterface<br />
  9. 9. Dependency Injection<br />Обявляет зависимости<br />запрашивает<br />Клиент<br />DI контейнер<br />внедряет<br />создает/возвращает<br />читает<br />MyClass : IMyInterface<br />MyClass : IMyInterface<br />Конфигурация<br />
  10. 10. Что такое Dependency Injection?<br />Инверсия зависимостей == Обращение контроля == Внедрение зависимостей == Dependency injection<br />Это принцип в объектно ориентированом программировании, который означает:<br /><ul><li>Модули верхнего уровня не должны зависеть от модулей нижнего уровня. Оба должны зависеть от абстракции.
  11. 11. Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций.</li></ul>Цель:<br /><ul><li>Уменьшить связность</li></li></ul><li>Пример связанного приложения<br />publicclassProgram<br />{<br />publicstaticvoid Main(string[] args)<br />{<br />varorderManager = newOrderManager();<br />orderManager.ProcessOrders();<br /> }<br />}<br />OrderManager<br />OrdersQueue<br />OrdersProcessor<br />
  12. 12. Пример связанного приложения<br />publicclassOrderManager<br />{<br />publicvoid ProcessOrders()<br /> {<br />var ordersQueue = newOrdersQueue();<br />IList<Order> orders = ordersQueue.GetPendingOrders();<br /> <br />if (orders.Count == 0)<br />thrownewEmptyOrdersQueueException();<br /> <br />var ordersProcessor = newManualOrdersProcessor();<br />foreach (Order order in orders)<br /> {<br /> ordersProcessor.ProcessOrder(order);<br /> }<br /> }<br />}<br />
  13. 13. Пример связанного приложения<br />publicclassOrderManager<br /> {<br />publicvoid ProcessOrders()<br /> {<br />var ordersQueue = newOrdersQueue();<br />IList<Order> orders = ordersQueue.GetPendingOrders();<br /> <br />if (orders.Count == 0)<br />thrownewNoOrdersException();<br /> <br />var ordersProcessor = newManualOrdersProcessor();<br />foreach (Order order in orders)<br /> {<br /> ordersProcessor.ProcessOrder(order);<br /> }<br /> }<br /> }<br />
  14. 14. Проблемы в примере<br /><ul><li>Тестируемость</li></ul>[TestClass]<br />publicclassOrderManagerTests<br /> {<br /> [TestMethod]<br />publicvoidshould_process_orders()<br /> {<br />varorderManager = newOrderManager();<br />orderManager.ProcessOrders();<br /> }<br /> }<br /><ul><li>Привязан к конкрентым сущностям, знает о них и создает их</li></li></ul><li>Применяем принципвручную<br /><ul><li>Будем привязыватся к интерфейсам</li></ul>publicinterfaceOrdersProcessor<br /> {<br />void Process(Order order);<br /> }<br />publicinterfaceIOrdersQueue<br /> {<br />List<Order> GetPendingOrders();<br /> }<br /><ul><li>Вынесемзависимости в readonlyполя класса, которые будут заполнятся из вне при инстанциировании объекта</li></li></ul><li>Применяем принципвручную<br />publicclassOrderManager{<br />privatereadonlyIOrdersQueueordersQueue;<br />privatereadonlyIOrdersProcessorordersProcessor;<br />publicOrderManager(IOrdersQueueordersQueue, <br />IOrdersProcessorordersProcessor)<br /> {<br />this.ordersProcessor = ordersProcessor;<br />this.ordersQueue = ordersQueue;<br /> }<br />publicvoidProcessOrders()<br /> { <br />IList<Order> orders = ordersQueue.GetPendingOrders();<br />if (orders.Count == 0)<br />thrownewNoOrdersException();<br />foreach (Orderorderin orders)<br /> {<br />ordersProcessor.Process(order);<br /> }<br /> }<br /> }<br />
  15. 15. Применяем используя контейнер<br />publicclassOrderManager<br />{<br /> [Inject]<br />publicIOrdersQueueordersQueue { get; set; }<br /> [Inject]<br />publicIOrdersProcessorordersProcessor { get; set; }<br />publicvoidProcessOrders()<br /> { <br />IList<Order> orders = ordersQueue.GetPendingOrders();<br />if (orders.Count == 0)<br />thrownewNoOrdersException();<br />foreach (Orderorderin orders)<br /> {<br />ordersProcessor.Process(order);<br /> }<br /> }<br />}<br />
  16. 16. Ручное DI vsКонтейнер<br /><ul><li>Оба варианта решают проблему класса с высокой связанностью
  17. 17. Если вручную, выполнение лишней работы по созданию и наполнению зависимостями
  18. 18. Если используюя контейнер досутпны возможности по «автоматическому» или «условному» наполнению зависимостями, не требующие никаких усилий
  19. 19. Время жизни объектов также должно гибко контролироватся, вручную – «лишняя работа»</li></li></ul><li>Формы Dependecy Injection<br /><ul><li>Constructor Injection</li></ul>[Inject]<br />publicOrderManager(IOrdersQueueordersQueue, IOrdersProcessorordersProcessor)<br />{<br />this.ordersProcessor= ordersProcessor;<br />this.ordersQueue= ordersQueue;<br />}<br /><ul><li>Property(Setter) Injection</li></ul>[Inject]<br />publicIOrdersProcessorordersProcessor { get; }<br /><ul><li>Method Injection</li></ul>[Inject]<br />voidDoSomeTask(IOrdersQueueorederQueue)<br />{<br />// ...<br />}<br />
  20. 20. Dependecy Injectionконтейнеры<br /><ul><li>StructureMap (AltDotNet)</li></ul>http://structuremap.sourceforge.net/Default.htm<br /><ul><li>Castle Windsor (AltDotNet)</li></ul>http://www.castleproject.org/container/index.html<br /><ul><li>Unity (Microsoft P&P)</li></ul>http://www.codeplex.com/unity<br /><ul><li>Ninject (open source)</li></ul>http://ninject.org<br /><ul><li>Много других (LinFu, например)</li></li></ul><li>Dependecy Injection используя nInject<br /><ul><li>Необходимо определить конфигурацию</li></ul>publicclassOrdersModule : NinjectModule<br />{<br /> publicoverridevoid Load()<br />{<br /> Bind<IOrdersQueue>().To<OrdersQueue>();<br />Bind<IOrdersQueue>().To<OrdersQueue>();<br />Bind<IOrdersProcessor>().To<ManualOrdersProcessor>();<br />Bind<OrderManager>().ToSelf();<br />}<br />}<br /><ul><li>Теперь можно использовать, например property injection</li></ul>[Inject]<br />publicIOrdersQueueordersQueue { get; set; }<br />
  21. 21. Dependecy Injection используя Unity<br /><ul><li>Необходимо определить конфигурацию</li></ul>varunityContainer = newUnityContainer()<br /> .RegisterType<IOrdersProcessor, ManualOrdersProcessor>()<br /> .RegisterType<IOrdersQueue, OrdersQueue>();<br />OrdersManager manager = unityContainer.Resolve<OrdersManager>();<br />manager.ProcessOrders();<br /><ul><li>Теперь можно использовать, например property injection</li></ul>[Dependency]<br />publicIOrdersQueueordersQueue { get; set; }<br />
  22. 22. “Продвинутая” конфигурация<br /><ul><li>Условный биндинг</li></ul>Bind<IOrdersProcessor>().To<ManualOrdersProcessor>().WhenTargetHas<MyAttribute>();<br />Bind<IOrdersProcessor>().To<ManualOrdersProcessor>()<br />.Only(When.Context.Target.Name.BeginsWith("Manual")); <br />var container = newUnityContainer()<br />.RegisterType<IOrdersQueue, OrdersQueue>()<br />.RegisterType<IOrdersProcessor, ManualOrdersProcessor>(newInjectionConstructor(10)); <br /><ul><li>Время жизни</li></ul>Bind<IOrdersProcessor>().To<ManualOrdersProcessor>().InSingletonScope();<br />Bind<IOrdersProcessor>().To<ManualOrdersProcessor>().InThreadScope();<br />var container = newUnityContainer() <br />.RegisterType<IOrdersProcessor, ManualOrdersProcessor>(newContainerControlledLifetimeManager())<br />
  23. 23. Преимущества от использования Dependecy Injection<br /><ul><li>Разделение конфигурирования связей и использования объектов
  24. 24. Уменьшается связывание</li></ul>Абстрактные интерфейсы не меняются<br />Конкретные объекты реализуют эти интерфейсы<br />Конкретные объекты проще заменить<br /><ul><li>Увеличение мобильности модулей
  25. 25. Улучшение изоляции объектов</li></ul>Уменьшается связность<br />Увеличивается тестируемость<br />Увеличивается удобство в поддержке<br />
  26. 26. Ссылки<br /><ul><li>http://martinfowler.com/articles/injection.html
  27. 27. http://www.objectmentor.com/resources/articles/dip.pdf
  28. 28. http://msdn.microsoft.com/en-us/library/aa973811.aspx
  29. 29. http://ninject.org/
  30. 30. http://unity.codeplex.com</li></li></ul><li>Спасибо за внимание:)<br />

×