Контейнер внедрения зависимостей в конструкторе
===============================================

Почему поместить контейнер в конструктор так плохо? Например, вы хотите разрешить класс B в конструкторе другого класса (C), потому что вам нужно, чтобы класс (B) использовался с разрешенными зависимостями (вы начинаете использовать класс C так, как хотите, как B, но с зависимости разрешены).

Why putting a container in a constructor is so bad?

Я полагаю, вы хотите передать контейнер в качестве аргумента конструктора. На самом деле это вариант шаблона локатора службы, который в этом контексте считается анти-шаблоном. Есть несколько причин, по которым вы можете этого не делать.

Во-первых, пользователи вашего класса будут знать только, что классу нужен контейнер для разрешения его зависимостей. Это количество информации равнозначно отсутствию информации, потому что вы все еще не знаете, от чего будет зависеть класс. Вы хотите написать модульный тест для класса? Вы должны заглянуть внутрь класса и посмотреть, какие типы он разрешает, смоделировать их и инициализировать контейнер для каждого теста. Это также означает, что изменения в некотором коде позволят ему скомпилироваться, но могут нарушить некоторые тесты: это тот случай, когда новый код опирается на класс, который, например, еще не зарегистрирован в контейнере.

Вторичный эффект, который часто встречается при использовании Service Locator, заключается в том, что вы никогда не можете быть уверены, что вы не получите исключение во время выполнения при запросе зависимостей. Каждый класс зарегистрирован правильно? Хотя некоторые контейнеры предоставляют возможность проверить, зарегистрирован ли каждый интерфейс, это не означает, что он зарегистрирован для правильного типа. Например, может случиться так, что тип будет зарегистрирован дважды в двух разных реализациях, и будет трудно заметить, может ли какой-либо фрагмент кода вызвать контейнер.

Лучшим решением этого является[Композиция Root pattern](http://blog.ploeh.dk/2011/07/28/CompositionRoot.aspx). [Этот пост в блоге](http://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx) также объясняет, почему Service Locator не может быть хорошей идеей.

РЕДАКТИРОВАТЬ в свете новых разработок:

По-видимому, вы используете стороннюю библиотеку, которая полагается на ваши классы, имеющие конструктор по умолчанию. Давайте предположим, что у вас нет никакого способа повлиять на создание ваших классов и что вы должны позволить этой платформе выполнять свою работу. Имейте в виду, что это может быть большим предположением, пожалуйста, исследуйте стороннюю библиотеку для возможности сделать это в первую очередь. На первый взгляд, фреймворки, такие как ASP.NET WebForms и WCF, не дают вам много шансов, но есть способы облегчить боль в этих случаях.

I meant just to create the container in the constructor, add the
 respective dependency to the container and resolve the object, which
 can be done by simply creating instance of the dependency object and
 use it to create the dependent object.

Я могу что-то упустить, но зачем вам регистрировать зависимость в конструкторе? Не могли бы вы просто разрешить это в конструкторе, но зарегистрировать это где-нибудь еще? Это все равно будет локатор службы, но вы, по крайней мере, поступите неправильно.

Why doing so in the constructor is a bad idea and doing so elsewhere
 is fine?

Делать этоanywhere но в одном месте это плохая идея. Зачем вам распространять регистрацию контейнеров повсюду? Если вы действительно чувствуете необходимость решить, какую реализацию интерфейса использовать во время выполнения, используйте что-то вроде Factory.

Итак, почему это плохо?

the client class depends on both implementation and interface, which doesn't make it better than newing the concrete class in the constructor.
the client class now also depends on the container, and the issues of Service Locator arise (see above), making now this approach worse than newing the concrete class.

Как сказал @Steven, вы теряете все преимущества Dependency Injection. Основной вопрос заключается в следующем: почему вы абсолютно хотите сделать DI в этом месте? Какие преимущества этого подхода вы хотели бы использовать? На основании ответа может быть несколько решений. Два примера из головы:

**Solution 1**: потерять DI для классов, создаваемых сторонней библиотекой.

**Solution 2**: Используйте комбинацию Bastard Injection + Service Locator. Два несправедливости могут исправить это в этом случае.

В этом случае вы не используете нелокальную зависимость в конструкторе, поскольку она разрешается локатором службы, поэтому у вас нет зависимостей от реализации.