Я видел много упоминаний о внедрении зависимостей (DI) и инверсии контроля (IOC), но я действительно не знаю, есть ли разница между ними или нет.
Я хотел бы начать использовать один или оба из них, но я немного смущен тем, как они отличаются.
Я видел много упоминаний о внедрении зависимостей (DI) и инверсии контроля (IOC), но я действительно не знаю, есть ли разница между ними или нет.
Я хотел бы начать использовать один или оба из них, но я немного смущен тем, как они отличаются.
Ответы:
Определения
Инверсия управления - это парадигма проектирования, целью которой является снижение осведомленности о конкретных реализациях из кода инфраструктуры приложения и предоставление большего контроля компонентам вашего приложения, специфичным для предметной области. В традиционной системе, спроектированной сверху вниз, логический поток приложения и понимания зависимостей переходит от верхних компонентов, разработанных первыми, к последним разработанным. Таким образом, инверсия управления - это почти буквальное изменение контроля и понимания зависимостей в приложении.
Внедрение зависимостей - это шаблон, используемый для создания экземпляров классов, на которые полагаются другие классы, не зная во время компиляции, какая реализация будет использоваться для предоставления этой функциональности.
Работая вместе
Инверсия управления может использовать внедрение зависимостей, потому что для создания компонентов, обеспечивающих определенные функциональные возможности, необходим механизм. Существуют и используются другие опции, например, активаторы, фабричные методы и т. Д., Но фреймворкам не нужно ссылаться на эти служебные классы, когда классы фреймворка могут вместо этого принять нужную (ые) зависимость (и).
Примеры
Одним из примеров этих концепций в работе является инфраструктура плагинов в Reflector . Плагины имеют большой контроль над системой, даже если приложение ничего не знало о плагинах во время компиляции. Для каждого из этих плагинов вызывается один метод: Initialize, если память служит, который передает управление плагину. Фреймворк не знает, что они будут делать, он просто позволяет им это делать. Контроль был взят из основного приложения и передан компоненту, выполняющему конкретную работу; инверсия контроля.
Инфраструктура приложения обеспечивает доступ к ее функциональности через различных поставщиков услуг. Плагин дает ссылки на поставщиков услуг при его создании. Эти зависимости позволяют плагину добавлять свои собственные пункты меню, изменять способ отображения файлов, отображать свою собственную информацию на соответствующих панелях и т. Д. Поскольку зависимости передаются через интерфейс, реализации могут измениться, и изменения не нарушат код до тех пор, пока договор остается в силе.
В то время фабричный метод использовался для создания плагинов с использованием информации о конфигурации, отражения и объекта Activator (по крайней мере, в .NET). Сегодня существуют инструменты, MEF для одного, которые позволяют использовать более широкий диапазон опций при внедрении зависимостей, включая возможность для среды приложения принимать список плагинов в качестве зависимости.
Резюме
Хотя эти концепции можно использовать и предоставлять преимущества независимо, вместе они позволяют писать гораздо более гибкий, повторно используемый и тестируемый код. Как таковые, они являются важными концепциями при разработке объектно-ориентированных решений.
источник
Хорошая статья для понимания МОК и DI http://martinfowler.com/articles/injection.html
МОК (инверсия контроля)
МОК означает
кодирование интерфейса (один компонент должен зависеть от интерфейса другого компонента, а не от impl), и, например,
удаление конкретного кода реализации компонента, например
МОК может быть достигнуто одним из следующих:
1. DI (Внедрение зависимостей)
2. Сервисный локатор
DI (Dependency Injection) контейнер
Определение импл во время выполнения, а не во время компиляции: определяет во время выполнения, какая конкретная реализация интерфейса будет использоваться на основе некоторого файла конфигурации (поэтому во время компиляции мы не знаем, какой импл будет использоваться, и, следовательно, увеличиваем конфигурируемость приложения) , Это реализация, в которой конкретное отношение между различными модулями определяется во время выполнения.
Создание impl после внедрения зависимостей: после определения impl он создает этот impl, сначала создавая все его зависимости (указанные в файле конфигурации), а затем вставляя эти зависимости в этот impl.
Управление жизненным циклом экземпляра: контейнеры DI обычно сохраняют ссылку только на объекты, для которых им необходимо управлять жизненными циклами или которые повторно используются для будущих инъекций, таких как синглтоны или мухи. Когда конфигурируется для создания новых экземпляров некоторых компонентов для каждого вызова контейнера, контейнер обычно просто забывает о созданном объекте. В противном случае сборщику мусора будет трудно собрать все эти объекты, когда они больше не используются.
источник
Я бы сказал, «Инверсия управления» - это способ разработки системы, в которой все модули рассматриваются как абстрактные объекты.
И «Внедрение зависимостей» - это реализация, в которой конкретное отношение между различными модулями определяется во время выполнения.
источник
Инверсия управления является общей концепцией, в функциональных языках обычно используется продолжение. Это позволит вам написать API, в котором обе стороны являются «вызывающими», а не «вызываемыми». В других, более статичных средах у вас нет такой возможности, поэтому вам нужен этот хак, чтобы вставить подсказки в поток управления.
источник