2

我有一个具有以下结构的类

class Measure
{
    public MeasureType measureType { get; set; }
    public readonly IMeasureService _service ;

    public Measure(IMeasureService service)
    {
        _service = service;
    }
    public Calculate()
    {
        _service.Calculate(this);
    }
}

所以我对不同的 measureTypes 有不同的 MeasureService 实现。是否可以使用 StructureMap 根据 measureType 注入对应的 MeasureService。

MeasureType 只是一个枚举类型,在整个实例中永远不会改变。

4

1 回答 1

2

StructureMap 不能被指示这样做,原因很简单:

  • 在创建实例时,measureType无法设置该属性。
  • 您不能IMeasureService在以后设置依赖项,因为它是readonly(并且可能应该private也是)

因此,这个问题的解决方案更多地与类的设计有关,而不是与 StructureMap 相关。

在这种情况下,我通常会选择以下解决方案:


IMeasureService1) 将选择正确实现的任务委托给不同的组件。

例如,可以调用该组件MeasureServiceFactory并具有以下实现:

public class MeasureServiceFactory
{
    private readonly Func<MeasureServiceType1> _type1Service;
    private readonly Func<MeasureServiceType2> _type2Service;

    public MeasureServiceFactory(
        Func<MeasureServiceType1> type1Service,
        Func<MeasureServiceType2> type2Service)
    {
        _type1Service = type1Service;
        _type2Service = type2Service;
    }

    public IMeasureService GetServiceForType(MeasureType type)
    {
        switch (type)
        {
            case MeasureType.Type1:
                return _type1Service();
            case MeasureType.Type2:
                return _type2Service();
            default:
                throw new ApplicationException("Unexpected measure type!");
        }
    }
}

请注意,StructureMap 将Func通过适当调用容器的GetInstance()方法自动注入这两个 s,以便正确解析所需的服务。

现在,Measure该类将不再具有直接IMeasureService依赖关系,而是依赖于工厂:

public class Measure
{
    public MeasureType measureType { get; set; }
    private readonly MeasureServiceFactory _measureServiceFactory;

    public Measure(MeasureServiceFactory measureServiceFactory)
    {
        _measureServiceFactory = measureServiceFactory;
    }

    public void Calculate()
    {
        var service = _measureServiceFactory.GetServiceForType(measureType);
        service.Calculate(this);
    }
}

请注意,不需要 StructureMap 配置。容器将能够正确解决所有问题。


2)为了保持Measure类不变,你可以MeasureServiceFactory实现IMeasureService接口:

public class MeasureServiceFactory : IMeasureService
{
    private readonly Func<MeasureServiceType1> _type1Service;
    private readonly Func<MeasureServiceType2> _type2Service;

    public MeasureServiceFactory(
        Func<MeasureServiceType1> type1Service,
        Func<MeasureServiceType2> type2Service)
    {
        _type1Service = type1Service;
        _type2Service = type2Service;
    }

    public void Calculate(Measure measure)
    {
        var service = GetServiceForType(measure.measureType);

        service.Calculate(measure);
    }

    private IMeasureService GetServiceForType(MeasureType type)
    {
        switch (type)
        {
            case MeasureType.Type1:
                return _type1Service();
            case MeasureType.Type2:
                return _type2Service();
            default:
                throw new ApplicationException("Unexpected measure type!");
        }
    }
}

现在,使用您的原始Measure课程,只需此 SM 配置即可使一切正常运行:

x.For<IMeasureService>().Use<MeasureServiceFactory>();

3)如果实现者内部的逻辑IMeasureService不是很复杂,考虑把它放在一个类中,并根据对象(你已经可以访问)执行不同的measureType事情Measure

我知道,这似乎是退后一步,但在某些情况下,我更愿意这样做:当业务逻辑不太复杂且不太可能改变时。

于 2013-08-05T18:13:49.693 回答