Прерванная цепь IoC - PullRequest
       1

Прерванная цепь IoC

2 голосов
/ 13 августа 2010

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

Проблема возникает в том, что я хочу использовать шаблон State в этих объектах IHardwareDevice и хочу, чтобы State был создан контейнером IoC.Есть ли хороший способ сделать это без непосредственного вызова контейнера IoC для разрешения объектов State, с помощью которых выполняется гидратация IHardwareDevice?

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

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

Ответы [ 3 ]

3 голосов
/ 14 августа 2010

Вот один из способов сделать это с Autofac 2.2 (http://autofac.org):

Во-первых, перечисление для различения состояний (составляющих некоторые вероятные значения):

public enum DeviceState { Online, Offline }

Затем состояние реализации, например:

public class OnlineState : IDeviceState { }

Затем зарегистрируйте каждое состояние с соответствующим ключом enum:

var builder = new ContainerBuilder();
builder.RegisterType<OnlineState>().Keyed<IDeviceState>(DeviceState.Online);
builder.RegisterType<OfflineState>().Keyed<IDeviceState>(DeviceState.Offline);
// Register other components here

Наконец, аппаратное устройство использует индекс для выбора состояний. Реализация IIndex автоматически обеспечивается контейнером:

public class Modem : IHardwareDevice
{
    IIndex<DeviceState, IDeviceState> _states;
    IDeviceState _currentState;

    public Modem(IIndex<DeviceState, IDeviceState> states)
    {
         _states = states;
         SwitchOn();
    }

    void SwitchOn()
    {
         _currentState = _states[DeviceState.Online];
    }
}

Надеюсь, это поможет.

Ник

2 голосов
/ 13 августа 2010

Большинство IoC-контейнеров, включая Windsor, имеют возможность передавать явные зависимости (параметры) в конструкторы разрешенных зависимостей; когда вы вызываете метод Resolve.

Так что да, вы можете явно передать ваш State объект в IHardwareDevice экземпляр, который вы разрешаете.

0 голосов
/ 14 августа 2010

У Виндзора есть очень мощное средство для автоматической реализации абстрактных фабрик - Типизированная фабричная база

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...