2010-01-28 4 views
3

Иногда при использовании инъекции зависимостей необходимо предоставить параметры, которые будут использоваться в конструкторе. Это то, что поддерживается в Unity (и других контейнерах для инъекций зависимостей), поэтому, когда он пытается создать экземпляр типа, он может предоставить ваши аргументы в качестве параметров в конструкторе.Передача параметров конструктора при разрешении типов в Unity: наилучшая практика

Мой вопрос: этот подход желателен?

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

Итак, это недостаток в том, как указаны сами интерфейсы (в .NET), например. следует ли указывать записи конструктора? Или эта функция (возможность предоставления параметров конструктора) была включена в Unity из-за какой-то другой необходимости?

Единственный реальный приемлемый подход (для меня), похоже, использует фабрику для создания классов реализации и делает инъекцию зависимостей на заводе.

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

(я не считаю, что это вопрос носит субъективный характер, так как, вероятно, следует один шаблон дизайна для данного типа инъекции зависимостей.)

EDIT:

Я хотел бы добавить, что моя главная проблема что я могу создать новый класс реализации, который имеет дополнительные параметры конструктора (где параметры конструктора не являются вещами, которые могут быть созданы единством).

ответ

0

Ответственность контейнеров IoC (например, Unity) заключается в подключении интерфейсов с конкретными реализациями. Это означает, что ваш контейнер должен знать интерфейс и как создать объект, который реализует интерфейс. Использование инъекции конструктора является совершенно законным и рекомендуемым способом. Unity создаст конкретную реализацию, когда ваше приложение запрашивает интерфейс через метод Resolve(). Контейнер Unity - это фабрика, которая создает ваши объекты, вы используете Unity, потому что вы не хотите сами внедрять эти заводы.

+0

Но если для конструктора требуются переменные экземпляра, я должен предоставить их самому Единству. Но интерфейс не указывает, что мне нужны эти параметры, так что, если я создам конкретную реализацию интерфейса, который имеет дополнительные параметры в конструкторе? –

2

Я не уверен, где у вас возникла мысль, что инъекция конструктора не соответствует DI. Я бы сказал, что реальная ситуация противоположна тому, что: инъекция конструктора является одной из наиболее распространенных моделей, используемых для достижения инъекции зависимостей - я бы сказал, что это наиболее распространенный шаблон, и этот вид безусловно, подкрепляется тем фактом, что в большинстве контейнеров Inversion of Control (контейнеры DI) в качестве предпочтительного механизма используется инжектор конструктора.

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

Что вы говорите, используя шаблон внедрения конструктора, это то, что «я удаляю жестко закодированные зависимости в моем классе, задавая их как параметры, переданные в конструктор - мой класс не может быть создан без этих зависимостей». Конечно, первая половина этого утверждения является сутью DI, но вторая половина усиливает это.

Зависимости - это детали реализации, которые должны быть легко изменены, обеспечивая гибкое, слабосвязанное решение. Они о том, как, а не о чем. Интерфейсы определяют, что. Поэтому я бы сказал, что ваше предложение об определении зависимостей в интерфейсах фактически противоречит концепции инъекции зависимостей.

И что касается вашего заявления о фабриках - это именно то, что представляют собой контейнеры МОК - большие крупные заводы, которые заботятся о дереве зависимостей решения, поэтому вам не нужно заботиться.

Редактировать

Я думаю, может быть, вы спрашиваете о том случае, когда вы хотите, чтобы предоставить параметр конструктора без зависимостей, таких как идентификатор для ссылочного объекта, или начальное состояние перечисления?

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

+0

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

0

Проблема здесь заключается в определении Инъекционного конструктора в Unity vs, например, в Castle.Windsor.

В Unity, если вам нужно ввести определенный параметр, скажем, AppSetting, вы также вынуждены поставлять все остальные параметры, тем самым фиксируя подпись конструктора. Однако в Castle.Windsor он принимает параметр, который вы предоставили, а затем использует механизм разрешения, чтобы обычным образом находить другие параметры.

Можно было бы ввести это в Unity, написав специальную стратегию Builder, которая использовала бы подход «наилучшего соответствия», который должен использовать конструктор, а не по умолчанию жадный/поставлять все, что по умолчанию.

Смежные вопросы