Могу ли я использовать контейнер IoC для создания зависимости, которая требует значения времени выполнения? - PullRequest
4 голосов
/ 16 февраля 2010

Я новичок в IoC, поэтому мне интересно, является ли это даже правильным инструментом для работы, которую я хочу сделать.

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

Скажем, например, когда пользователь из одной организации создает рабочее задание, руководителю этого пользователя необходимо отправить электронное письмо. Но для всех других организаций это электронное письмо отправлять не нужно. Классическая стратегия, модель такого рода вещи.

У меня вопрос, могу ли я как-то проинструктировать контейнер IoC для просмотра определенного значения времени выполнения (в данном случае OrganizationId зарегистрированного пользователя), чтобы определить, какую реализацию IWorkOrderProcessor внедрить в конструктор объект, который нуждается в этом?

В настоящее время я использую Windsor, но примеры использования других контейнеров подойдут.

Ответы [ 4 ]

3 голосов
/ 16 февраля 2010

Windsor имеет точку расширения, которая идеально подходит для мультитенантных приложений: IHandlerSelector.

Это позволяет вам кодировать ваше приложение, как если бы оно не было мультитенантным. Многопользовательская логика вытесняется из вашей бизнес-логики.

1 голос
/ 16 февраля 2010

Большинство хороших контейнеров IOC поддерживают такой вид использования.

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

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

В вашем примере, если у вас действительно есть истинный вариант использования для шаблона стратегии, где вы бы реализовали это поведение, даже если бы вы не использовали IOC в качестве внедренного объекта стратегии (используя некоторый подход Factory), тогда я бы сказал, да, иди вперед с внедрением МОК.

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

0 голосов
/ 16 февраля 2010

Это общая проблема с DI, и ответ всегда состоит в том, чтобы создать и внедрить Abstract Factory . В вашем случае вы можете определить интерфейс следующим образом:

public interface IWorkerProcessorFactory
{
    IWorkerProcessor Create(int organizationId);
}

Во всех классах, где у вас есть идентификатор организации и вам нужен экземпляр IWorkerProcessor, вы берете зависимость от IWorkerProcessorFactory и вызываете его метод Create.

Этот шаблон работает с DI для бедного человека или с любым контейнером DI, который вы хотели бы использовать.

Вот более полный пример: Невозможно объединить Factory / DI

0 голосов
/ 16 февраля 2010

Я думаю, что Вы можете, потому что контейнер IoC может использовать различные типы инъекций:

  1. конструктор инъекций,
  2. сеттер впрыска,
  3. интерфейс впрыска (метод впрыска)

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

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

Все зависит от того, как реализован ваш контейнер.

Кстати: были заданы похожие вопросы: IoC: Существующие объекты среды выполнения, а не инициализированные контейнером предварительные условия для компонентов

...