Требовать зависимости для каждого вызова метода из UnityContainer - PullRequest
2 голосов
/ 12 июня 2011

Так что в моем текущем коде я работаю над каким-то менеджером уведомлений.

Идея состоит в том, что мой основной BL будет использовать этот менеджер уведомлений для каждого вызова метода.Следовательно, вероятно, будет только один менеджер уведомлений (синглтон в единстве, я думаю).

Когда вы используете диспетчер уведомлений, вы можете отправить уведомление через SMS \ Email \ Other.на самом деле происходит то, что диспетчер уведомлений разрешает «INotificationProvidor», который также находится в контейнере единицы.Это решение делается по имени, как в «SMS», «Email», «Other».

Вот небольшой фрагмент кода:

var notificationProvidor =
    m_Container.Resolve<INotificationProvidor<TResult>>(
        typeOfNotification.ToString());

ResultMessage<TResult> notificationResult = notificationProvidor
    .SendNotification(source, destination, message, subject);

Как вы можете видеть, менеджер уведомлений удерживаетэкземпляр контейнера для разрешения каждого из «INotificationProvidor».

Как можно устранить эту необходимость удержания контейнера в диспетчере уведомлений?со следующими ограничениями:

  • Не все типы «INotificationProvidor» (SMS, электронная почта, другие) могут быть зарегистрированы в контейнере.
  • Будет только один менеджер уведомлений,(поскольку BL, использующий его, будет активен в течение приложения и получит его от DI)

Короче ... разрешение зависимости для вызова метода.:)

Ответы [ 3 ]

2 голосов
/ 12 июня 2011

Я бы использовал Заводской шаблон . Либо создайте свой собственный с вашим собственным интерфейсом и реализацией. Или я считаю, что многие IoC-фреймворки умны, когда вы пытаетесь разрешить Func<string, INotificationProvidor<TResult>>, они сами динамически создают фабричный метод.

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

1 голос
/ 12 июня 2011

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

Вот интерфейс фабрики:

interface IProvidersResolver 
{
    INotificationProvider<TNotification> Resolve<TNotification>();
}

Вот как вы можете использовать его в NotificationManager:

// here you hold the reference to the resolver
private IProvidersResolver _resolver;

// here you use injected factory to resolve INotificationProvider
void UseResolver()
{
    INotificationProvider<SomeNotification> provider = _resolver.Resole<SomeNotification>();
}

Таким образом, вы держите ссылку на IProviderResolver (только на заводе)Это обычная практика.В качестве альтернативы вы можете:

  1. создать экземпляр NotificationManager для каждого INotificationProvider<TNotification>
  2. передать ссылку на контейнер в NotificationManager
0 голосов
/ 12 июня 2011

Я думаю, что вы можете решить эту проблему, имея зависимость от фабрики, которая превратит typeOfNotification в фактический NotificationProvider в классах, которые должны иметь возможность получить NotificationPrivider на основе укуса.Класс фабрики будет создан контейнером, и все доступные поставщики уведомлений будут внедрены в его конструктор.

Затем контейнер может выполнить всю проводку за вас в корне композиции, но каждый метод получит NotificationProvider на основе строкового значения typeOfNotification

.
...