В простых терминах и/или в псевдокоде высокого уровня, как работает контейнер DI и как он используется?Простейшее объяснение того, как работает контейнер DI?
ответ
В своей основе контейнер DI создает объекты на основе сопоставлений между интерфейсами и конкретными типами.
Это позволит запросить абстрактный тип из контейнера:
IFoo f = container.Resolve<IFoo>();
Это требует, чтобы вы ранее настроены контейнера к карте от IFoo к конкретному классу, который реализует IFoo (например, Foo).
Это само по себе не будет особенно впечатляющим, но DI Контейнеры сделать больше:
- Они используют Auto-проводниковой, что означает, что они могут автоматически понять, что если IFoo сопоставляется Foo и IBar сопоставляется Bar, но Foo имеет зависимость от IBar, он создаст экземпляр Foo с баром, когда вы запросите IFoo.
- Они управляют сроком службы компонентов. Вы каждый раз хотите, чтобы каждый экземпляр Foo каждый раз, но в других случаях вам может понадобиться один и тот же экземпляр. Вы можете даже хотеть новые экземпляры Foo каждый раз, но введенная панель должна оставаться тем же самым экземпляром.
После того, как вы начнете пытаться управлять вручную Состав и времена жизни вы должны начать ценить услуги, предоставляемые в DI контейнер :)
Многие DI Контейнеры могут сделать гораздо больше, чем выше, но те, являются основными услугами. В большинстве контейнеров есть варианты для configuring via either code or XML.
Что касается собственно использование контейнеров, Krzysztof Kozmic только что опубликовал a good overview.
Вы настраиваете контейнер DI, чтобы он знал о ваших интерфейсах и типах - как каждый интерфейс сопоставляется с типом.
Когда вы вызываете на него Resolve
, он просматривает отображение и возвращает запрошенный объект.
Некоторые контейнеры DI используют соглашения по конфигурации, например, если вы определяете интерфейс ISomething
, он будет искать конкретный тип Something
для создания и возврата.
«Это ничего более, чем фантазии хэш таблицы объектов.»
Хотя выше массивное преуменьшение, что это легкий способ думать о них. Учитывая коллекцию, если вы попросите один и тот же экземпляр класса - контейнер DI решит, предоставить ли вам кешированную версию или новую или так далее.
Их использование упрощает и упрощает процесс установления связей. Представьте, что у вас есть следующие псевдоклассы.
class House(Kitchen, Bedroom)
// Use kitchen and bedroom.
end
class Kitchen()
// Code...
end
class Bedroom()
// Code...
end
Построив дом боль без DI контейнера, вам нужно создать экземпляр спальни, а затем экземпляр кухни. Если у этих объектов тоже есть зависимости, вам нужно их подключить. В свою очередь, вы можете потратить много строк кода, просто проводя объекты. Только тогда вы могли бы создать действительный дом. Используя контейнер DI/IOC (Inversion of Control), вы говорите, что хотите домашний объект, контейнер DI будет рекурсивно создавать каждую из своих зависимостей и возвращать вам дом.
без DI/контейнер МОК:
house = new House(new Kitchen(), new Bedroom());
С DI/МОК Контейнер:
house = // some method of getting the house
В конце концов они делают код легко следовать, проще писать и переложить ответственность объектов проводки вместе от проблемы.
Следует отметить, что DI хорош, потому что он мешает вам писать собственные сложные конструкторы и собственный код для настройки вещей и кучу других подобных вещей. Хотя да, вы не нуждаетесь в этом, неплохо иметь возможность использовать существующую библиотеку для обработки всего этого материала для вас. Он делает настройку приложений Java (C# - не моя область знаний) выглядит немного похоже на работу с белым, непоследовательным, сложным языком сценариев ... –
Short & Sweet & free от токсичных аналоговых автомобилей! – Shog9