StructureMap -注入条件类



我有一个名为IProcessor的接口,有多个实现,如ABCProcessor, PQRProcessor。我想利用基于外部参数的特定处理器。如何使用StructureMap实现相同的功能?

我正在寻找相同的命名实例。

您可以使用工厂模式:

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();
}

你的问题的最佳解决方案是通过实现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;
}

通过这样做,您可以在运行时委托给正确的实现,而消费者仍然忽略您在运行时对此做出决定的事实。现在不是向消费者注射ABCProcessorPQRProcessor,而是向消费者注射ProxyProcessor。例如,ProxyProcessor的对象图可能是这样的:

IProcessor processor =
    new ProxyProcessor(
        abc: new ABCProcessor(), 
        pqr: new PQRProcessor(), 
        config: new SqlProcessorConfig("constr"));
请注意,与使用工厂相比,这个解决方案有几个优点,例如:
  • 它防止对消费者进行任何更改;消费者对此无动于衷。
  • 它防止给消费者带来不必要的复杂性;使用工厂方法,消费者必须处理额外的依赖项。这会使代码和测试变得复杂。
  • 导致对象图以延迟的方式构造,从而使对象图的验证变得复杂。

如果你想知道为什么工厂从来都不是正确的抽象,请阅读这篇文章

最新更新