2016-11-01 2 views
0

У меня есть 1 интерфейс с именем IProcessor, имеющий несколько реализаций, таких как ABCProcessor, PQRProcessor. Я хочу использовать конкретный процессор на основе внешних параметров. Как я могу добиться того же, используя StructureMap.StructureMap - Inject Conditional Class

Я ищу именованные экземпляры для того же.

+0

Каковы эти «внешние параметры»? – Steven

+0

Внешние параметры похожи на конфигурационные ключи, которые управляют выбором процессора. – Anup

+0

Вам не нужно ничего условного, когда значение является постоянным. Значения конфигурации не изменяются в течение всего срока действия приложения, поэтому вы можете просто настроить sreucturemap безоговорочно на основе этих значений. – Steven

ответ

0

Вы можете использовать шаблон фабрики:

public interface IProcessorFactory 
{ 
    IProcessor Create(int dropDownValue); 
} 

public class ProcessorFactory : IProcessorFactory 
{ 
    private readonly IContainer _container; 
    public ProcessorFactory(IContainer container) 
    { 
     _container = container; 
    } 

    public IProcessor Create() 
    { 
     if(//your condition) 
      return _container.GetInstance<ABCProcessor>(); 

     _container.GetInstance<PQRProcessor>(); 
    } 
} 

(или просто вводят необходимые зависимости вместо контейнера) , а затем просто

private readonly IProcessorFactory _processorFactory; 

public MvcController(IProcessorFactory processorFactory) 
{ 
    _processorFactory = processorFactory; 
} 

public void Method() 
{ 
    var processor = _processorFactory.Create(); 
} 
0

Лучшее решение для вашей проблемы, чтобы скрыть знание о существовании множественных реализаций и выбор между ними от потребителя путем реализации прокси-реализации для IProcessor:

public sealed ProxyProcessor : IProcessor 
{ 
    private readonly ABCProcessor abc; 
    private readonly PQRProcessor pqr; 
    private readonly IProcessorConfig config; 

    public ProxyProcessor(ABCProcessor abc, PQRProcessor pqr, IProcessorConfig config) { 
     this.abc = abc; 
     this.pqr = pqr; 
     this.config = config; 
    } 

    // Implement IProcessor methods to forward to the CurrentProcessor. 
    public void Process() => CurrentProcessor.Process(); 

    private IProcessor CurrentProcessor => config.ProcessorType == "ABC" ? abc : pqr; 
} 

Делая это, вы можете делегировать правильное применение во время выполнения в то время как потребитель остается не обращая внимания на тот факт, что вы принять решение во время выполнения об этом. Теперь вместо того, чтобы вводить потребителям ABCProcessor или PQRProcessor, теперь вы вводите потребителям ProxyProcessor. Например, это то, как объектный граф для ProxyProcessor может выглядеть следующим образом:

IProcessor processor = 
    new ProxyProcessor(
     abc: new ABCProcessor(), 
     pqr: new PQRProcessor(), 
     config: new SqlProcessorConfig("constr")); 

Обратите внимание, что это решение имеет ряд преимуществ по сравнению с использованием фабрики, такие как:

  • Это предотвращает необходимости вносить какие-либо изменения в потребителей; потребители остаются без внимания.
  • Это предотвращает внедрение излишней сложности в потребителей; с заводским подходом потребители должны иметь дело с дополнительной зависимостью. Это усложняет код и тесты.
  • Он вызывает построение графиков объектов с задержкой, что затрудняет проверку графов объектов.

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