Шаблон разработки стратегии с контейнерами IOC - в частности, Ninject

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

Рассматриваемый класс в настоящее время принимает в конструкторе четыре параметра, каждый из которых представляет алгоритм.

Как с помощью Ninject (или обобщенного подхода) я мог бы по-прежнему использовать IOC, но использовать шаблон стратегии?

Текущее ограничение заключается в том, что мое ядро ​​(контейнер) знает о каждом интерфейсе алгоритма, но может быть привязано только к одному конкретному классу. На данный момент я вижу единственный способ обойти это - передать все восемь алгоритмов при построении, но использовать разные интерфейсы, но это кажется совершенно ненужным. Я бы не стал этого делать, если бы не использовал контейнер IOC, поэтому должен быть какой-то способ обойти это.

Пример кода:

class MyModule : NinjectModule 
{
    public override void Load() 
    {
        Bind<Person>().ToSelf();
        Bind<IAlgorithm>().To<TestAlgorithm>();
        Bind<IAlgorithm>().To<ProductionAlgorithm>();
    }
}

Человеку необходимо использовать оба алгоритма, чтобы я мог переключаться во время выполнения. Но привязан только TestAlgorithm, так как он первый в контейнере.


person Finglas    schedule 06.03.2010    source источник


Ответы (2)


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

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

Вместо того, чтобы регистрировать отдельные стратегии в контейнере, вы регистрируете фабрику.

Вполне возможно написать полный API, чтобы он был дружественным к DI, но все же Д. И. Контейнер-независимый.

person Mark Seemann    schedule 06.03.2010

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

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

person Jeff Sternal    schedule 06.03.2010