SlideShare a Scribd company logo
Dependency Injection на примере Unity и nInjectКалита РоманTaskManagementSoft
ПланЧто такое Dependency Injection?Как проблемы решает и какие преимущества дает при проектированииКакие есть формы DIDI контейнеры в .NET
Качественный код/системаКод
Некоторые проблемы при проектировании приложенийПо версии GoF
Сильносвязанные системы
Сильносвязанные системысложноО каких качествах кода может идти речь?
Уменьшаем связанность
Фабрика, Локатор, МетодЗапрашивает IMyInterfaceКлиентФабрика, Локатор, МетодСоздает MyClassMyClassIMyInterfaceРеализует IMyInterface
Dependency InjectionОбявляет зависимостизапрашиваетКлиентDI контейнервнедряетсоздает/возвращаетчитаетMyClass : IMyInterfaceMyClass : IMyInterfaceКонфигурация
Что такое Dependency Injection?Инверсия зависимостей == Обращение контроля == Внедрение зависимостей == Dependency injectionЭто принцип в объектно ориентированом программировании, который означает:Модули верхнего уровня не должны зависеть от модулей нижнего уровня. Оба должны зависеть от абстракции.
Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций.Цель:Уменьшить связностьПример связанного приложенияpublicclassProgram{publicstaticvoid Main(string[] args){varorderManager = newOrderManager();orderManager.ProcessOrders();    }}OrderManagerOrdersQueueOrdersProcessor
Пример связанного приложенияpublicclassOrderManager{publicvoid ProcessOrders()        {var ordersQueue = newOrdersQueue();IList<Order> orders = ordersQueue.GetPendingOrders(); if (orders.Count == 0)thrownewEmptyOrdersQueueException(); var ordersProcessor = newManualOrdersProcessor();foreach (Order order in orders)            {                ordersProcessor.ProcessOrder(order);            }        }}
Пример связанного приложенияpublicclassOrderManager    {publicvoid ProcessOrders()        {var ordersQueue = newOrdersQueue();IList<Order> orders = ordersQueue.GetPendingOrders(); if (orders.Count == 0)thrownewNoOrdersException(); var ordersProcessor = newManualOrdersProcessor();foreach (Order order in orders)            {                ordersProcessor.ProcessOrder(order);            }        }    }
Проблемы в примереТестируемость[TestClass]publicclassOrderManagerTests    {        [TestMethod]publicvoidshould_process_orders()        {varorderManager = newOrderManager();orderManager.ProcessOrders();        }    }Привязан к конкрентым сущностям, знает о них и создает ихПрименяем принципвручнуюБудем привязыватся к интерфейсамpublicinterfaceOrdersProcessor {void Process(Order order); }publicinterfaceIOrdersQueue {List<Order> GetPendingOrders(); }Вынесемзависимости в readonlyполя класса, которые будут заполнятся из вне при инстанциировании объектаПрименяем принципвручнуюpublicclassOrderManager{privatereadonlyIOrdersQueueordersQueue;privatereadonlyIOrdersProcessorordersProcessor;publicOrderManager(IOrdersQueueordersQueue, IOrdersProcessorordersProcessor)        {this.ordersProcessor = ordersProcessor;this.ordersQueue = ordersQueue;        }publicvoidProcessOrders()        {            IList<Order> orders = ordersQueue.GetPendingOrders();if (orders.Count == 0)thrownewNoOrdersException();foreach (Orderorderin orders)            {ordersProcessor.Process(order);            }        }    }
Применяем используя контейнерpublicclassOrderManager{        [Inject]publicIOrdersQueueordersQueue { get; set; }        [Inject]publicIOrdersProcessorordersProcessor { get; set; }publicvoidProcessOrders()        {            IList<Order> orders = ordersQueue.GetPendingOrders();if (orders.Count == 0)thrownewNoOrdersException();foreach (Orderorderin orders)            {ordersProcessor.Process(order);            }        }}
Ручное DI vsКонтейнерОба варианта решают проблему класса с высокой связанностью
Если вручную, выполнение лишней работы по созданию и наполнению зависимостями
Если используюя контейнер досутпны возможности по «автоматическому» или «условному» наполнению зависимостями, не требующие никаких усилий
Время жизни объектов также должно гибко контролироватся, вручную – «лишняя работа»Формы Dependecy InjectionConstructor Injection[Inject]publicOrderManager(IOrdersQueueordersQueue, IOrdersProcessorordersProcessor){this.ordersProcessor= ordersProcessor;this.ordersQueue= ordersQueue;}Property(Setter) Injection[Inject]publicIOrdersProcessorordersProcessor { get; }Method Injection[Inject]voidDoSomeTask(IOrdersQueueorederQueue){// ...}
Dependecy InjectionконтейнерыStructureMap (AltDotNet)http://structuremap.sourceforge.net/Default.htmCastle Windsor (AltDotNet)http://www.castleproject.org/container/index.htmlUnity (Microsoft P&P)http://www.codeplex.com/unityNinject (open source)http://ninject.orgМного других (LinFu, например)Dependecy Injection используя nInjectНеобходимо определить конфигурациюpublicclassOrdersModule : NinjectModule{     publicoverridevoid Load(){          Bind<IOrdersQueue>().To<OrdersQueue>();Bind<IOrdersQueue>().To<OrdersQueue>();Bind<IOrdersProcessor>().To<ManualOrdersProcessor>();Bind<OrderManager>().ToSelf();}}Теперь можно использовать, например property injection[Inject]publicIOrdersQueueordersQueue { get; set; }
Dependecy Injection используя UnityНеобходимо определить конфигурациюvarunityContainer = newUnityContainer()               .RegisterType<IOrdersProcessor, ManualOrdersProcessor>()               .RegisterType<IOrdersQueue, OrdersQueue>();OrdersManager manager = unityContainer.Resolve<OrdersManager>();manager.ProcessOrders();Теперь можно использовать, например property injection[Dependency]publicIOrdersQueueordersQueue { get; set; }
“Продвинутая” конфигурацияУсловный биндингBind<IOrdersProcessor>().To<ManualOrdersProcessor>().WhenTargetHas<MyAttribute>();Bind<IOrdersProcessor>().To<ManualOrdersProcessor>().Only(When.Context.Target.Name.BeginsWith("Manual"));     var container = newUnityContainer().RegisterType<IOrdersQueue, OrdersQueue>().RegisterType<IOrdersProcessor, ManualOrdersProcessor>(newInjectionConstructor(10)); Время жизниBind<IOrdersProcessor>().To<ManualOrdersProcessor>().InSingletonScope();Bind<IOrdersProcessor>().To<ManualOrdersProcessor>().InThreadScope();var container = newUnityContainer() .RegisterType<IOrdersProcessor, ManualOrdersProcessor>(newContainerControlledLifetimeManager())
Преимущества от использования Dependecy InjectionРазделение конфигурирования связей и использования объектов
Уменьшается связываниеАбстрактные интерфейсы не меняютсяКонкретные объекты реализуют эти интерфейсыКонкретные объекты проще заменитьУвеличение мобильности модулей
Улучшение изоляции объектовУменьшается связностьУвеличивается тестируемостьУвеличивается удобство в поддержке
Ссылкиhttp://martinfowler.com/articles/injection.html

More Related Content

PPTX
Moxy. Как правильно пользоваться? / Юрий Шмаков (Arello Mobile)
PPT
ZFConf 2011: Гибкая архитектура Zend Framework приложений с использованием De...
PDF
Java осень 2014 занятие 3
PPT
Методики «Inversion of Control» и «Dependency Injection». Применение в Spring.
PPTX
Bytecode
PDF
Олексій Стульніков “WinAppDriver – автоматизація Desktop ніколи не була такою...
PPTX
MVP, Moxy. Как правильно пользоваться
PDF
Java осень 2014 занятие 5
Moxy. Как правильно пользоваться? / Юрий Шмаков (Arello Mobile)
ZFConf 2011: Гибкая архитектура Zend Framework приложений с использованием De...
Java осень 2014 занятие 3
Методики «Inversion of Control» и «Dependency Injection». Применение в Spring.
Bytecode
Олексій Стульніков “WinAppDriver – автоматизація Desktop ніколи не була такою...
MVP, Moxy. Как правильно пользоваться
Java осень 2014 занятие 5

What's hot (20)

PPTX
Java весна 2013 лекция 9
PPTX
Модульная структура
PDF
Виктор Брыкcин — Как всё починить и ничего не сломать: работа со сложным кодо...
PPTX
Разработка WPF приложений в стиле ViewModel First
PPTX
Создание графического интерфейса пользователя мобильных Android приложений (ч...
PPT
Moxy – реализация MVP под Android. С щепоткой магии
PPTX
Unit tests final
PDF
Глава 2: Среда разработки NetBeans
PPTX
Как приручить реактивное программирование в XAML приложениях
PPTX
Mikhail Valkov_Antipatterns
PPTX
Как приручить реактивное программирование
PPTX
PDF
Rambler.iOS #3: Test-Driven Development в iOS
PPTX
Объять необъятное, или как использовать несколько MVVM фреймворков в одном XA...
PDF
Лекция Android. БД SQLite, ContentProvider, Loader
PDF
MVVM в WinForms – DevExpress Way (теория и практика)
PPTX
Unit тесты java
PDF
Евгений Сафронов "Тестирование. точка зрения разработчика"
PPTX
Использование Mock объектов в модульном тестировании
PPTX
Java осень 2012 лекция 9
Java весна 2013 лекция 9
Модульная структура
Виктор Брыкcин — Как всё починить и ничего не сломать: работа со сложным кодо...
Разработка WPF приложений в стиле ViewModel First
Создание графического интерфейса пользователя мобильных Android приложений (ч...
Moxy – реализация MVP под Android. С щепоткой магии
Unit tests final
Глава 2: Среда разработки NetBeans
Как приручить реактивное программирование в XAML приложениях
Mikhail Valkov_Antipatterns
Как приручить реактивное программирование
Rambler.iOS #3: Test-Driven Development в iOS
Объять необъятное, или как использовать несколько MVVM фреймворков в одном XA...
Лекция Android. БД SQLite, ContentProvider, Loader
MVVM в WinForms – DevExpress Way (теория и практика)
Unit тесты java
Евгений Сафронов "Тестирование. точка зрения разработчика"
Использование Mock объектов в модульном тестировании
Java осень 2012 лекция 9
Ad

Similar to Dependency Injection на примере Unity и NInject (19)

PDF
Эволюция управления зависимостями в коде
PDF
DI в C++ тонкости и нюансы
PDF
Кирилл Маурин «Проектирование и разработка модульных приложений»
PDF
Кирилл Маурин «Проектирование и разработка модульных приложений»
PDF
Паттерны быстрой разработки WPF MVVM бизнес-приложений
PDF
Архитектура в Agile: слабая связность
PPTX
Dependency injection
PDF
ук 03.001.02 2011
PPT
паттерны программирования
PPTX
SOLID. Принципы объектно ориентированного дизайна
PDF
Илья Ефимов «IoC/DI на примере Autofac»
PDF
Илья Ефимов «IoC/DI на примере Autofac»
PPTX
SOLID Principles in the real world
PPT
Управление зависимостями в программном коде
PDF
IoC & Dependency Injection
PPTX
07 Архитектура информационных систем. Принципы GRASP
PDF
SOLID & GRASP
PDF
ук 03.003.01 2011
Эволюция управления зависимостями в коде
DI в C++ тонкости и нюансы
Кирилл Маурин «Проектирование и разработка модульных приложений»
Кирилл Маурин «Проектирование и разработка модульных приложений»
Паттерны быстрой разработки WPF MVVM бизнес-приложений
Архитектура в Agile: слабая связность
Dependency injection
ук 03.001.02 2011
паттерны программирования
SOLID. Принципы объектно ориентированного дизайна
Илья Ефимов «IoC/DI на примере Autofac»
Илья Ефимов «IoC/DI на примере Autofac»
SOLID Principles in the real world
Управление зависимостями в программном коде
IoC & Dependency Injection
07 Архитектура информационных систем. Принципы GRASP
SOLID & GRASP
ук 03.003.01 2011
Ad

More from akrakovetsky (17)

PPTX
Alco calculator
PPTX
qiss.IM - wp7rocks.com
PPTX
Семантический HTML5 - iForum
PPTX
Что нового в Visual Studio 2010 и .Net 4.0
PPTX
jQuery для ASP.NET разработчиков
PPTX
Функциональное программирование на F#
PPT
Переходим на Windows 7 и Windows 2008 R2
PPTX
Разработка и раскрутка iPhone приложений "с нуля"
PPT
Основи розробки ігор на платформі XNA
PPT
PPTX
Введение в Microsoft Silverlight 3.0
PPTX
ASP.NET 4.0 Cache Extensibility
PPTX
Microsoft .NET User Group Вінниця #4
PPT
What's new in Visual Studio 2010.
PPTX
Что нового в ASP.NET 4
PPSX
Введение в Windows Communication Foundation
PPTX
Microsoft User Group Vinnitsya
Alco calculator
qiss.IM - wp7rocks.com
Семантический HTML5 - iForum
Что нового в Visual Studio 2010 и .Net 4.0
jQuery для ASP.NET разработчиков
Функциональное программирование на F#
Переходим на Windows 7 и Windows 2008 R2
Разработка и раскрутка iPhone приложений "с нуля"
Основи розробки ігор на платформі XNA
Введение в Microsoft Silverlight 3.0
ASP.NET 4.0 Cache Extensibility
Microsoft .NET User Group Вінниця #4
What's new in Visual Studio 2010.
Что нового в ASP.NET 4
Введение в Windows Communication Foundation
Microsoft User Group Vinnitsya

Dependency Injection на примере Unity и NInject

Editor's Notes

  • #4: В процессе разработки и проектирования приложения мы стремимся чтобы код и само приложение в целом соответствовали определенному набору критериев, которые в нашем понимании являются критериями качественного кода, критериями хорошо спроектированой системы. Эти критерии известны и сформировались с опытом. Это расширяемость, сопровождаемость, простота, читабельность и тестируемость.В процессе проектирования/перепроектирования/рефакторинга мы сталкиваемся с проблемами которые …
  • #5: В процессе разработки код программы постоянно меняется. Вот некоторые проблемы с которыми сталкиваются разработчики при изменении/перепроектировании систем.При создании объекта явно указывается класс. Задание имени класса при создании объекта привязывает к конкретной реализации, что усложняет изменение объекта в будущем. Т.е. поддерживать такой объект будет намного сложнее, а связанность объектов повышается.При сильной связанности внутри программы код становится более хрупким. Внесение изменений затруднено, так как изменения приходится вносить в Внесение изменений в одном месте кода ведет к изменениям в другом, в следствии чего число багов увеличивается
  • #6: This is another option for an Overview slides using transitions.
  • #7: В процессе разработки код программы постоянно меняется. Вот некоторые проблемы с которыми сталкиваются разработчики при изменении/перепроектировании систем.При создании объекта явно указывается класс. Задание имени класса при создании объекта привязывает к конкретной реализации, что усложняет изменение объекта в будущем. Т.е. поддерживать такой объект будет намного сложнее, а связанность объектов повышается.При сильной связанности внутри программы код становится более хрупким. Внесение изменений затруднено, так как изменения приходится вносить в Внесение изменений в одном месте кода ведет к изменениям в другом, в следствии чего число багов увеличивается
  • #8: В процессе разработки код программы постоянно меняется. Вот некоторые проблемы с которыми сталкиваются разработчики при изменении/перепроектировании систем.При создании объекта явно указывается класс. Задание имени класса при создании объекта привязывает к конкретной реализации, что усложняет изменение объекта в будущем. Т.е. поддерживать такой объект будет намного сложнее, а связанность объектов повышается.При сильной связанности внутри программы код становится более хрупким. Внесение изменений затруднено, так как изменения приходится вносить в Внесение изменений в одном месте кода ведет к изменениям в другом, в следствии чего число багов увеличивается