Некоторое время я использовал Dependency Injection (DI), внедряя либо в конструктор, свойство или метод. Я никогда не чувствовал необходимости использовать контейнер Inversion of Control (IoC). Однако чем больше я читаю, тем больше давление со стороны сообщества вызывает использование контейнера IoC.
Я играл с контейнерами .NET, такими как StructureMap , NInject , Unity и Funq . Я до сих пор не понимаю, как контейнер IoC может улучшить / улучшить мой код.
Я также боюсь начать использовать контейнер на работе, потому что многие из моих коллег увидят код, который они не понимают. Многие из них могут неохотно изучать новые технологии.
Пожалуйста, убедите меня, что мне нужно использовать контейнер IoC. Я собираюсь использовать эти аргументы, когда общаюсь с коллегами-разработчиками на работе.
Ответы:
Вау, не могу поверить, что Джоэл поддержит это:
через это:
Многие люди не понимают, что ваша цепочка зависимостей может стать вложенной, и это быстро становится громоздким, чтобы связать их вручную. Даже на фабриках дублирование вашего кода просто не стоит.
Контейнеры IoC могут быть сложными, да. Но для этого простого случая я показал, что это невероятно легко.
Ладно, давайте еще раз объясним это. Допустим, у вас есть некоторые сущности или объекты модели, которые вы хотите привязать к интеллектуальному интерфейсу. Этот умный интерфейс (назовем его Shindows Morms) хочет, чтобы вы внедрили INotifyPropertyChanged, чтобы он мог отслеживать изменения и обновлять интерфейс соответствующим образом.
«Хорошо, это звучит не так сложно», поэтому вы начинаете писать.
Вы начинаете с этого:
..и в конечном итоге это :
Это отвратительный слесарный код, и я утверждаю, что если вы пишете такой код вручную, вы крадете у своего клиента . Есть лучший, умный способ работы.
Когда-нибудь слышали этот термин, работать умнее, а не усерднее?
Ну, представьте, какой-нибудь умный парень из вашей команды подошел и сказал: «Вот более легкий путь»
Если вы сделаете свои свойства виртуальными (успокойтесь, это не так уж сложно), мы можем автоматически влиять на поведение этих свойств. (Это называется AOP, но не беспокойтесь об имени, сосредоточьтесь на том, что он собирается сделать для вас)
В зависимости от того, какой инструмент IoC вы используете, вы можете сделать что-то похожее на это:
Пуф! Все это руководство INotifyPropertyChanged BS теперь автоматически генерируется для вас на каждом установщике виртуальных свойств рассматриваемого объекта.
Это волшебство? ДА ! Если вы можете доверять тому факту, что этот код выполняет свою работу, тогда вы можете спокойно пропустить все это свойство, оборачивая mumbo-jumbo. Вам нужно решить бизнес-проблемы.
Некоторые другие интересные применения инструмента IoC для выполнения AOP:
источник
Я с тобой, Вадим. Контейнеры IoC используют простую, элегантную и полезную концепцию и делают ее тем, что вам придется изучать в течение двух дней с помощью руководства на 200 страниц.
Я лично озадачен тем, как сообщество IoC взяло красивую, элегантную статью Мартина Фаулера и превратило ее в набор сложных фреймворков, обычно с 200-300 страницами руководств.
Я стараюсь не быть осуждающим (ХАХА!), Но я думаю, что люди, которые используют контейнеры IoC, (А) очень умны и (Б) испытывают недостаток в сочувствии к людям, которые не так умны, как они. Все имеет для них смысл, поэтому им трудно понять, что многие обычные программисты смущают эти концепции. Это проклятие знаний . Люди, которые понимают контейнеры IoC, испытывают затруднения, полагая, что есть люди, которые этого не понимают.
Наиболее ценным преимуществом использования контейнера IoC является то, что вы можете иметь переключатель конфигурации в одном месте, который позволяет вам переключаться между, скажем, тестовым режимом и рабочим режимом. Например, предположим, у вас есть две версии ваших классов доступа к базе данных ... одна версия, которая активно регистрировалась и выполняла много проверок, которую вы использовали во время разработки, и другая версия без регистрации или проверки, которая была чрезвычайно быстрой для работы. Приятно иметь возможность переключаться между ними в одном месте. С другой стороны, это довольно тривиальная проблема, которую легко решить простым способом без использования контейнеров IoC.
Я считаю, что если вы используете контейнеры IoC, ваш код, честно говоря, станет намного сложнее для чтения. Количество мест, на которые нужно посмотреть, чтобы выяснить, что пытается сделать код, увеличивается как минимум на одно. И где-то на небесах кричит ангел.
источник
Предположительно никто не заставляет вас использовать инфраструктуру DI-контейнера. Вы уже используете DI, чтобы отделить свои классы и улучшить тестируемость, так что вы получаете много преимуществ. Короче говоря, вы предпочитаете простоту, что, как правило, хорошо.
Если ваша система достигает уровня сложности, когда ручное DI становится рутинным делом (то есть увеличивает обслуживание), взвесьте это в сравнении с кривой обучения команды каркаса контейнера DI.
Если вам нужен больший контроль над управлением временем жизни зависимостей (то есть, если вы чувствуете необходимость реализации шаблона Singleton), посмотрите на контейнеры DI.
Если вы используете DI-контейнер, используйте только те функции, которые вам нужны. Пропустите файл конфигурации XML и настройте его в коде, если этого достаточно. Придерживайтесь конструктора инъекций. Основы Unity или StructureMap можно сжать до нескольких страниц.
Марк Сееманн (Mark Seemann) пишет об этом в блоге: когда использовать DI-контейнер
источник
На мой взгляд, преимуществом IoC является возможность централизовать настройку ваших зависимостей.
Если вы используете внедрение зависимостей, ваш код может выглядеть следующим образом
Если бы вы использовали статический класс IoC, в отличие от более сложных файлов конфигурации, IMHO, вы могли бы получить что-то вроде этого:
Тогда ваш класс статического IoC будет выглядеть следующим образом, я использую Unity здесь.
источник
Контейнеры IoC также хороши для загрузки глубоко вложенных зависимостей классов. Например, если у вас был следующий код, использующий Depedency Injection.
Если вы загрузили все эти зависимости и контейнер IoC, вы можете разрешить службу CustomerService, и все дочерние зависимости будут автоматически разрешены.
Например:
источник
Я фанат декларативного программирования (посмотрите, на сколько вопросов SQL я отвечаю), но контейнеры IoC, на которые я смотрел, кажутся слишком загадочными для их собственной пользы.
... или, возможно, разработчики IoC-контейнеров не в состоянии написать четкую документацию.
... или оба они верны в той или иной степени.
Я не думаю, что концепция контейнера IoC плохая. Но реализация должна быть достаточно мощной (то есть гибкой), чтобы быть полезной в широком спектре приложений, но при этом простой и понятной.
Это, наверное, шесть из полутора десятков других. Реальное приложение (не игрушка или демо) обязательно должно быть сложным, составляя множество угловых случаев и исключений из правил. Либо вы заключаете эту сложность в императивный код, либо в декларативный код. Но вы должны представить это где-то.
источник
Использование контейнера в основном сводится к переходу от императивного / скриптового стиля инициализации и конфигурации к декларативному . Это может иметь несколько различных полезных эффектов:
Конечно, могут быть трудности:
источник
Мне кажется, что вы уже создали свой собственный контейнер IoC (используя различные шаблоны, которые были описаны Мартином Фаулером) и спрашиваете, почему чья-то реализация лучше вашей.
Итак, у вас есть куча кода, который уже работает. И задаетесь вопросом, почему вы хотели бы заменить его на чью-либо реализацию.
Плюсы за рассмотрение стороннего контейнера IoC
Cons
Итак, взвесьте свои плюсы против ваших минусов и примите решение.
источник
Я думаю, что большая часть IoC достигается за счет использования DI. Поскольку вы уже делаете это, остальная часть выгоды является дополнительной.
Значение, которое вы получите, будет зависеть от типа приложения, над которым вы работаете:
Для мультитенантов контейнер IoC может позаботиться о некотором коде инфраструктуры для загрузки различных клиентских ресурсов. Когда вам нужен компонент, специфичный для клиента, используйте пользовательский селектор для обработки логики и не беспокойтесь об этом из своего клиентского кода. Конечно, вы можете построить это самостоятельно, но вот пример того, как IoC может помочь.
Благодаря множеству точек расширения IoC может использоваться для загрузки компонентов из конфигурации. Это обычная вещь для сборки, но инструменты предоставляются контейнером.
Если вы хотите использовать AOP для решения нескольких сквозных задач, IoC предоставляет ловушки для перехвата вызовов методов. Это не так часто делается для проектов, но IoC делает это проще.
Ранее я писал такую функциональность, но если мне понадобится какая-либо из этих функций, я бы предпочел использовать предварительно созданный и протестированный инструмент, если он соответствует моей архитектуре.
Как уже упоминалось другими, вы также можете централизованно настроить, какие классы вы хотите использовать. Хотя это может быть хорошей вещью, оно идет за счет неверного направления и усложнения. Основные компоненты для большинства приложений не заменяются, поэтому сделать компромисс немного сложнее.
Я использую контейнер IoC и ценю функциональность, но должен признать, что заметил компромисс: мой код становится более понятным на уровне класса и менее четким на уровне приложения (т. Е. Визуализирует поток управления).
источник
Я выздоравливающий наркоман МОК. Мне трудно оправдать использование МОК для DI в большинстве случаев в эти дни. Контейнеры IOC жертвуют проверкой времени компиляции и, предположительно, в ответ дают вам «простую» настройку, сложное управление временем жизни и на лету обнаружение зависимостей во время выполнения. Я считаю, что потеря проверки времени компиляции и возникающая во время выполнения магия / исключения не стоят наворотов в подавляющем большинстве случаев. В крупных корпоративных приложениях им очень трудно следить за тем, что происходит.
Я не покупаю аргумент централизации, потому что вы можете очень легко централизовать статическую настройку, используя абстрактную фабрику для своего приложения и неукоснительно откладывая создание объекта до абстрактной фабрики, то есть, делая надлежащий DI.
Почему бы не сделать статический безмагнитный DI вроде этого:
Ваша конфигурация контейнера - ваша абстрактная фабричная реализация, ваши регистрации - реализации абстрактных членов. Если вам нужна новая одноэлементная зависимость, просто добавьте еще одно абстрактное свойство в абстрактную фабрику. Если вам нужна временная зависимость, просто добавьте другой метод и вставьте его как Func <>.
Преимущества:
Я рекомендую скептикам начать следующий проект по созданию «зеленого поля» и честно спросить себя, в какой момент вам нужен контейнер. Позже легко включить контейнер IOC, поскольку вы просто заменяете фабричную реализацию модулем конфигурации контейнера IOC.
источник
Самым большим преимуществом использования контейнеров IoC для меня (лично я использую Ninject) было устранение передачи параметров и других видов глобальных объектов состояния.
Я не программирую для Интернета, у меня консольное приложение, и во многих местах в глубине дерева объектов мне нужен доступ к настройкам или метаданным, указанным пользователем, которые создаются в совершенно отдельной ветви дерева объектов. С IoC я просто говорю Ninject, что нужно обращаться с настройками как синглтоном (потому что всегда есть только один их экземпляр), запрашивать настройки или словарь в конструкторе и нажимать ... они волшебным образом появляются, когда они мне нужны!
Без использования контейнера IoC мне пришлось бы передавать настройки и / или метаданные через 2, 3, ..., n объектов, прежде чем они фактически использовались объектом, который нуждался в этом.
У контейнеров DI / IoC есть много других преимуществ, о которых здесь подробно рассказывают другие, и переход от идеи создания объектов к запрашиванию объектов может быть утомительным, но использование DI было очень полезно для меня и моей команды, поэтому, возможно, вы сможете добавить его в ваш арсенал!
источник
Фреймворки IoC отлично подходят, если вы хотите ...
... выбросить тип безопасности. Многие (все?) Фреймворки IoC заставляют вас выполнять код, если вы хотите быть уверены, что все правильно подключено. «Эй! Надеюсь, я все настроил, чтобы мои 100 инициализаций не потерпели неудачу в работе, исключая нулевой указатель!»
... помет ваш код с глобалов (рамки IoC являются все о меняющихся глобальных состояний).
... написать дрянной код с неясными зависимостями, которые трудно реорганизовать, так как вы никогда не узнаете, что зависит от чего.
Проблема с IoC в том, что люди, которые их используют, писали такой код
что явно ошибочно, поскольку зависимость между Foo и Bar жесткая. Тогда они поняли, что было бы лучше написать код, как
что также ошибочно, но не так очевидно. В Haskell типом
Foo()
будет,IO Foo
но вы действительно не хотитеIO
-part, и это должно быть предупреждающим признаком того, что с вашим дизайном что-то не так, если вы его получили.Чтобы избавиться от этого (часть IO), получите все преимущества IoC-фреймворков и ни одного из его недостатков, которые вы могли бы вместо этого использовать абстрактную фабрику.
Правильное решение будет что-то вроде
или, может быть
и вводить (но я бы не назвал это вводить) бар.
Также: посмотрите это видео с Эриком Мейером (изобретателем LINQ), где он говорит, что DI для людей, которые не знают математику (и я не мог согласиться с этим): http://www.youtube.com/watch?v = 8Mttjyf-8P4
В отличие от г-на Спольского, я не верю, что люди, которые используют IoC-фреймворки, очень умны - я просто считаю, что они не знают математику.
источник
IBar
, это на самом делеIO IBar
) .. И да, в примере с Haskell Я не могу получить нулевую ссылку.Я обнаружил, что правильная реализация Dependency Injection вынуждает программистов использовать множество других практик программирования, которые помогают улучшить тестируемость, гибкость, удобство обслуживания и масштабируемость кода: такие практики, как принцип единой ответственности, разделение проблем и кодирование против API. Такое ощущение, что я вынужден писать более модульные классы и методы размером с кусочек, что облегчает чтение кода, потому что его можно брать кусками размером с кусочек.
Но он также имеет тенденцию создавать довольно большие деревья зависимостей, которыми гораздо легче управлять через каркас (особенно если вы используете соглашения), чем вручную. Сегодня я хотел что-то очень быстро протестировать в LINQPad, и я подумал, что будет слишком сложно создать ядро и загрузить свои модули, и в итоге я написал это вручную:
Оглядываясь назад, можно было бы быстрее использовать платформу IoC, так как модули по большей части определяют все это по соглашению.
Потратив некоторое время на изучение ответов и комментариев по этому вопросу, я убежден, что люди, которые выступают против использования контейнера IoC, не практикуют истинное внедрение зависимостей. Примеры, которые я видел, - это практики, которые обычно путают с внедрением зависимостей. Некоторые люди жалуются на трудности с «чтением» кода. Если все сделано правильно, подавляющее большинство вашего кода должно быть идентичным при использовании DI вручную, как при использовании контейнера IoC. Разница должна заключаться в нескольких «точках запуска» в приложении.
Другими словами, если вам не нравятся контейнеры IoC, вы, вероятно, делаете инъекцию зависимостей не так, как предполагалось.
Еще один момент: внедрение зависимости действительно невозможно сделать вручную, если вы используете отражение где-либо. Хотя я ненавижу то, что отражается на навигации по коду, вы должны признать, что есть определенные области, где этого действительно нельзя избежать. Например, ASP.NET MVC пытается создать экземпляр контроллера путем отражения в каждом запросе. Чтобы выполнить внедрение зависимостей вручную, вы должны сделать каждый контроллер «корневым контекстом», вот так:
Теперь сравните это с тем, чтобы позволить инфраструктуре DI сделать это за вас:
Используя структуру DI, обратите внимание, что:
ISimpleWorkflowInstanceMerger
, я могу проверить, что он используется так, как я ожидаю, без необходимости подключения к базе данных или чего-либо еще.ISimpleWorkflowInstanceMerger
интерфейс. Это позволяет мне разбивать приложение на отдельные модули и поддерживать настоящую многоуровневую архитектуру, что, в свою очередь, делает вещи более гибкими.Типичное веб-приложение будет иметь довольно много контроллеров. Вся боль, связанная с выполнением DI вручную на каждом контроллере, будет накапливаться по мере роста вашего приложения. Если у вас есть приложение с единственным корневым контекстом, которое никогда не пытается создать экземпляр службы с помощью отражения, то это не такая большая проблема. Тем не менее, любое приложение, использующее Dependency Injection, станет чрезвычайно дорогим в управлении, как только оно достигнет определенного размера, если только вы не используете какой-то фреймворк для управления графом зависимостей.
источник
Всякий раз, когда вы используете ключевое слово «new», вы создаете конкретную зависимость от класса, и в вашей голове должен прозвучать небольшой сигнал тревоги. Становится все труднее тестировать этот объект изолированно. Решение состоит в том, чтобы запрограммировать интерфейсы и внедрить зависимость, чтобы объект мог быть протестирован модулем с чем угодно, что реализует этот интерфейс (например, mocks).
Беда в том, что вы должны где-то строить объекты. Фабричный шаблон - это один из способов снять связь с вашими POXO (Plain Old, «вставьте сюда свой язык OO», «Объекты»). Если вы и ваши коллеги пишете такой код, то контейнер IoC - это следующее «поэтапное улучшение», которое вы можете внести в свою кодовую базу. Это вытеснит весь этот мерзкий шаблонный код фабрики из ваших чистых объектов и бизнес-логики. Они получат это и полюбят это. Черт возьми, поговори с компанией о том, почему ты любишь это, и возбуди всех.
Если ваши коллеги еще не занимаются DI, то я бы посоветовал вам сначала сосредоточиться на этом. Распространите информацию о том, как написать чистый код, который легко тестируется. Чистый DI-код - это сложная задача, когда вы окажетесь там, перенос логики связывания объектов из классов Factory в контейнер IoC должен быть относительно тривиальным.
источник
Поскольку все зависимости четко видны, это способствует созданию компонентов, которые слабо связаны и в то же время легко доступны и могут повторно использоваться в приложении.
источник
Вам не нужен контейнер IoC.
Но если вы строго следуете шаблону DI, вы обнаружите, что его использование удалит тонну избыточного, скучного кода.
Во всяком случае, это лучшее время для использования библиотеки / фреймворка - когда вы понимаете, что она делает, и можете сделать это без библиотеки.
источник
Просто так получилось, что я выискивал самодельный код DI и заменил его на IOC. Я, вероятно, удалил более 200 строк кода и заменил их примерно на 10. Да, мне пришлось немного изучить, как использовать контейнер (Winsor), но я инженер, работающий над интернет-технологиями в 21-го века, так что я привык к этому. Я, вероятно, потратил около 20 минут на просмотр как. Это стоило моего времени.
источник
По мере того, как вы продолжаете отделять свои классы и инвертировать ваши зависимости, классы продолжают оставаться маленькими, а «граф зависимостей» продолжает увеличиваться в размере. (Это неплохо.) Использование основных функций контейнера IoC делает подключение всех этих объектов тривиальным, но выполнение этого вручную может стать очень обременительным. Например, что если я хочу создать новый экземпляр «Foo», но для этого нужен «Bar». А «Бар» нуждается в «А», «В» и «С». И каждому из них нужны еще 3 вещи и т. Д. И т. Д. (Да, я не могу придумать хорошие поддельные имена :)).
Использование контейнера IoC для построения вашего графа объектов снижает сложность и переводит его в одноразовую конфигурацию. Я просто говорю «создай мне« Foo »», и он выясняет, что нужно для его создания.
Некоторые люди используют контейнеры IoC для гораздо большей инфраструктуры, что хорошо для сложных сценариев, но в этих случаях я согласен, что это может запутать и затруднить чтение и отладку кода для новых разработчиков.
источник
То же самое о Единстве. Становитесь слишком большими, и вы можете услышать скрип в стропилах.
Меня никогда не удивляет, когда люди начинают говорить о том, что чистый код IoC - это те же самые люди, которые когда-то говорили о том, что шаблоны в C ++ были элегантным способом вернуться в 90-е годы, но в наши дни они будут воспринимать их как загадочные. , Бах!
источник
В мире .NET AOP не слишком популярен, поэтому для DI фреймворк - ваш единственный реальный выбор, независимо от того, пишете ли вы один или используете другой фреймворк.
Если вы использовали AOP, вы можете внедрить его при компиляции приложения, что более распространено в Java.
У DI есть много преимуществ, таких как уменьшенная связь, поэтому модульное тестирование проще, но как вы будете его реализовывать? Вы хотите использовать рефлексию, чтобы сделать это самостоятельно?
источник
Так прошло уже почти 3 года, а?
50% тех, кто высказался в пользу IoC-фреймворков, не понимают разницы между IoC-фреймворками и IoC. Я сомневаюсь, что они знают, что вы можете написать код без развертывания на сервере приложений
Если мы возьмем самую популярную среду Java Spring, то конфигурация IoC перенесена из XMl в код и теперь выглядит следующим образом
`@Configuration открытый класс AppConfig {
} `И нам нужна структура, чтобы сделать это, почему именно?
источник
Честно говоря, я не нахожу много случаев, когда нужны контейнеры IoC, и в большинстве случаев они просто добавляют ненужную сложность.
Если вы используете его просто для упрощения построения объекта, я должен спросить: вы создаете экземпляр этого объекта в нескольких местах? Не подойдет ли вам синглтон? Вы меняете конфигурацию во время выполнения? (Переключение типов источников данных и т. Д.).
Если да, то вам может понадобиться контейнер IoC. Если нет, то вы просто перемещаете инициализацию от того места, где разработчик может легко ее увидеть.
Кто сказал, что интерфейс лучше наследования? Скажем, вы тестируете Сервис. Почему бы не использовать конструктор DI и создавать макеты зависимостей, используя наследование? Большинство услуг, которыми я пользуюсь, имеют только несколько зависимостей. Выполнение модульного тестирования таким способом предотвращает поддержку множества бесполезных интерфейсов и означает, что вам не нужно использовать Resharper, чтобы быстро найти объявление метода.
Я считаю, что для большинства реализаций утверждение о том, что контейнеры IoC удаляют ненужный код, является мифом.
Во-первых, настройка контейнера в первую очередь. Затем вам все еще нужно определить каждый объект, который нужно инициализировать. Таким образом, вы не сохраняете код при инициализации, вы перемещаете его (если ваш объект не используется более одного раза. Он лучше как Singleton?). Затем для каждого объекта, который вы инициализировали таким образом, вы должны создать и поддерживать интерфейс.
У кого-нибудь есть мысли по этому поводу?
источник
ShippingCostCalculator
илиProductUIPresentation
, или любую другую стратегию / реализацию, в пределах той же самой базы кода , развернув только один измененный файл XML.Вам понадобится контейнер IoC, если вам нужно централизовать конфигурацию ваших зависимостей, чтобы их можно было легко заменить в массовом порядке. Это имеет смысл в TDD, где много зависимостей поменяны местами, но между ними мало взаимозависимости. Это делается за счет запутывания потока управления строительством объекта до некоторой степени, поэтому важно иметь хорошо организованную и достаточно документированную конфигурацию. Также хорошо иметь причину сделать это, иначе это просто абстракция позолота . Я видел, что это сделано так плохо, что его перетянули до эквивалента оператора goto для конструкторов.
источник
Вот почему. Проект называется IOC-with-Ninject. Вы можете скачать и запустить его с Visual Studio. В этом примере используется Ninject, но ВСЕ операторы 'new' находятся в одном месте, и вы можете полностью изменить работу своего приложения, изменив используемый модуль связывания. Пример настроен так, что вы можете привязать к поддельной версии служб или реальной версии. В небольших проектах это может не иметь значения, но в больших проектах это большое дело.
Просто чтобы прояснить, преимущества, как я их вижу: 1) ВСЕ новые операторы в одном месте в корне кода. 2) Полностью перефакторинг кода с одним изменением. 3) Дополнительные очки за «крутой фактор», потому что это ... хорошо: круто. :п
источник
Я постараюсь выяснить, почему МОК может не подходить с моей точки зрения.
Как и во всем остальном, контейнер IOC (или, как сказал бы Эйнштейн, I = OC ^ 2) - это концепция, которую вы должны решить для себя, нужно ли вам это в коде или нет. Последние крики моды о МОК - это только мода. Не поддавайтесь моде, это первое. Существует множество концепций, которые вы можете реализовать в своем коде. Прежде всего, я использую внедрение зависимостей, так как я начал программировать и узнал сам термин, когда он был популяризирован под этим именем. Контроль зависимостей - очень старая тема, и до сих пор она решалась триллионами способов, в зависимости от того, что отделилось от чего. Отделение всего от всего - это чепуха. Проблема с контейнером IOC заключается в том, что он пытается быть таким же полезным, как Entity Framework или NHibernate. Хотя написание объектно-реляционного преобразователя просто необходимо, как только вам нужно соединить любую базу данных с вашей системой, контейнер IOC не всегда необходим. Итак, когда контейнер IOC полезен:
1: не так часто, что в вашем коде столько зависимостей, или вы знаете о них на ранних стадиях разработки. Абстрактное мышление полезно, когда необходимо абстрактное мышление.
2: Сопряжение вашего кода со сторонним кодом - проблема HuGe. Я работал с кодом, которому более 10 лет и который в то время следовал причудливым и продвинутым концепциям ATL, COM, COM + и так далее. Теперь вы ничего не можете сделать с этим кодом. То, что я говорю, - то, что продвинутая концепция дает очевидное преимущество, все же это отменено в долгосрочной перспективе с самим устаревшим преимуществом. Это только сделало все это более дорогим.
3: разработка программного обеспечения достаточно трудна. Вы можете расширить его до неузнаваемых уровней, если позволите какой-то продвинутой концепции врезаться в ваш код. Существует проблема с IOC2. Хотя это разъединяет зависимости, оно также разъединяет логический поток. Представьте, что вы нашли ошибку, и вам нужно установить перерыв, чтобы изучить ситуацию. IOC2, как и любая другая продвинутая концепция, делает это более сложным. Исправление ошибки в концепции труднее, чем исправление ошибки в простом коде, потому что, когда вы исправляете ошибку, концепция должна снова соблюдаться. (Просто для примера: C ++ .NET постоянно меняет синтаксис настолько, что вам нужно тщательно продумать, прежде чем проводить рефакторинг какой-либо более старой версии .NET.) Так в чем же проблема с IOC? Проблема в разрешении зависимостей. Логика решения обычно скрыта в самом IOC2, написано может быть необычным образом, что вам нужно учиться и поддерживать. Будет ли ваш сторонний продукт появится через 5 лет? Microsoft не было.
Синдром «мы знаем как» написан повсеместно в отношении IOC2. Это похоже на автоматизацию тестирования. На первый взгляд удачный срок и идеальное решение, вы просто выполняете все свои тесты за ночь и видите результаты утром. Действительно больно объяснять компании за компанией, что на самом деле означает автоматизированное тестирование. Автоматическое тестирование определенно не является быстрым способом уменьшения количества ошибок, которые вы можете внести в одночасье, чтобы повысить качество вашего продукта. Но мода делает это понятие раздражающе доминирующим. IOC2 страдает тем же синдромом. Считается, что вам нужно реализовать это, чтобы ваше программное обеспечение было хорошим. Каждое недавнее интервью меня спросили, внедряю ли я IOC2 и автоматизацию. Это признак моды: у компании есть часть кода, написанная на MFC, которую они не откажутся.
Вы должны изучить IOC2, как и любое другое понятие в программном обеспечении. Решение о необходимости использования IOC2 принимается командой и компанией. Однако, по крайней мере, ВСЕ вышеупомянутые аргументы должны быть упомянуты до принятия решения. Только если вы видите, что положительная сторона перевешивает отрицательную сторону, вы можете принять положительное решение.
В IOC2 нет ничего плохого, кроме того, что он решает только те проблемы, которые он решает, и вводит проблемы, которые он вводит. Ничего больше. Однако идти против моды очень сложно, у них вспотел рот, приверженцы чего-либо. Странно, что никого из них нет, когда проблема с их причудой становится очевидной. Многие концепции в индустрии программного обеспечения были защищены, потому что они приносят прибыль, пишутся книги, проводятся конференции, производятся новые продукты. Это мода, обычно недолговечная. Как только люди находят что-то еще, они полностью от них отказываются. IOC2 полезен, но показывает те же признаки, что и многие другие исчезнувшие концепции, которые я видел. Я не знаю, выживет ли это. Для этого нет правила. Вы думаете, если это полезно, оно выживет. Нет, это не так. Достаточно одной большой богатой компании, и концепция может умереть в течение нескольких недель. Посмотрим. NHibernate выжил, EF занял второе место. Может быть, IOC2 тоже выживет. Не забывайте, что большинство концепций в разработке программного обеспечения не имеют ничего общего, они очень логичны, просты и очевидны, и иногда сложнее запомнить текущее соглашение об именах, чем понять саму концепцию. Знание IOC2 делает разработчика лучшим разработчиком? Нет, потому что, если разработчик не смог придумать концепцию, схожую по своей природе с IOC2, ему или ей будет трудно понять, какую проблему решает IOC2, используя ее, будет выглядеть искусственно, и он или она может начать использовать ее ради того, чтобы быть своего рода политкорректным. Не забывайте, что большинство концепций в разработке программного обеспечения не имеют ничего общего, они очень логичны, просты и очевидны, и иногда сложнее запомнить текущее соглашение об именах, чем понять саму концепцию. Знание IOC2 делает разработчика лучшим разработчиком? Нет, потому что, если разработчик не смог придумать концепцию, схожую по своей природе с IOC2, ему или ей будет трудно понять, какую проблему решает IOC2, используя ее, будет выглядеть искусственно, и он или она может начать использовать ее ради того, чтобы быть своего рода политкорректным. Не забывайте, что большинство концепций в разработке программного обеспечения не имеют ничего общего, они очень логичны, просты и очевидны, и иногда сложнее запомнить текущее соглашение об именах, чем понять саму концепцию. Знание IOC2 делает разработчика лучшим разработчиком? Нет, потому что, если разработчик не смог придумать концепцию, схожую по своей природе с IOC2, ему или ей будет трудно понять, какую проблему решает IOC2, используя ее, будет выглядеть искусственно, и он или она может начать использовать ее ради того, чтобы быть своего рода политкорректным. Знание IOC2 делает разработчика лучшим разработчиком? Нет, потому что, если разработчик не смог придумать концепцию, схожую по своей природе с IOC2, ему или ей будет трудно понять, какую проблему решает IOC2, используя ее, будет выглядеть искусственно, и он или она может начать использовать ее ради того, чтобы быть своего рода политкорректным. Знание IOC2 делает разработчика лучшим разработчиком? Нет, потому что, если разработчик не смог придумать концепцию, схожую по своей природе с IOC2, ему или ей будет трудно понять, какую проблему решает IOC2, используя ее, будет выглядеть искусственно, и он или она может начать использовать ее ради того, чтобы быть своего рода политкорректным.
источник
Лично я использую IoC как своего рода структурную карту своего приложения (да, я также предпочитаю StructureMap;)). Это облегчает замену моих обычных реализаций интерфейса реализациями Moq во время тестов. Создать тестовую настройку можно так же просто, как выполнить новый вызов init для моей IoC-инфраструктуры, заменив какой-либо класс моей границы теста фиктивным.
Вероятно, это не то, для чего нужен IoC, но я использую его чаще всего ...
источник
КОНТЕЙНЕР МОК РЕШАЕТ ПРОБЛЕМУ, КОТОРУЮ У ВАС НЕ МОЖЕТ БЫТЬ, НО ЭТО ХОРОШАЯ ПРОБЛЕМА
http://kozmic.net/2012/10/23/ioc-container-solves-a-problem-you-might-not-have-but-its-a-nice-problem-to-have/
источник
вам не нужна структура для достижения внедрения зависимости. Вы можете сделать это с помощью основных Java-концепций. http://en.wikipedia.org/wiki/Dependency_injection#Code_illustration_using_Java
источник
Я понимаю, что это довольно старый пост, но он все еще достаточно активен, и я подумал, что хотел бы добавить пару моментов, которые еще не были упомянуты в других ответах.
Я скажу, что я согласен с преимуществами внедрения зависимостей, но я предпочитаю создавать объекты и управлять ими самостоятельно, используя шаблон, не похожий на тот, который описал Maxm007 в своем ответе. Я обнаружил две основные проблемы с использованием сторонних контейнеров:
1) Наличие сторонней библиотеки, управляющей временем жизни ваших объектов "автоматически", может привести к неожиданным результатам. Мы обнаружили, что особенно в больших проектах у вас может быть гораздо больше копий объекта, чем вы ожидаете, и больше, чем если бы вы вручную управляли жизненными циклами. Я уверен, что это зависит от используемой платформы, но проблема, тем не менее, существует. Это также может быть проблематично, если ваш объект содержит ресурсы, подключения к данным и т. Д., Поскольку объект может иногда жить дольше, чем вы ожидаете. Поэтому неизбежно контейнеры IoC имеют тенденцию увеличивать использование ресурсов и объем памяти приложения.
2) Контейнеры IoC, на мой взгляд, являются формой «программирования черного ящика». Я обнаружил, что, в частности, наши менее опытные разработчики склонны злоупотреблять ими. Это позволяет программисту не думать о том, как объекты должны быть связаны друг с другом или как их разъединять, потому что предоставляет им механизм, с помощью которого они могут просто захватывать любой объект из воздуха. Например, может быть веская причина, по которой ObjectA никогда не должен знать непосредственно об ObjectB, но вместо создания фабрики, моста или сервисного локатора неопытный программист просто скажет: «Нет проблем, я просто возьму ObjectB из контейнера IoC. ». На самом деле это может привести к усилению связывания объектов, что IoC должен предотвратить.
источник
Внедрение зависимостей в проекте ASP.NET может быть выполнено с помощью нескольких строк кода. Я предполагаю, что есть некоторое преимущество в использовании контейнера, когда у вас есть приложение, которое использует несколько внешних интерфейсов и нуждается в модульных тестах.
источник