StructureMap 不能被指示这样做,原因很简单:
- 在创建实例时,
measureType
无法设置该属性。
- 您不能
IMeasureService
在以后设置依赖项,因为它是readonly
(并且可能应该private
也是)
因此,这个问题的解决方案更多地与类的设计有关,而不是与 StructureMap 相关。
在这种情况下,我通常会选择以下解决方案:
IMeasureService
1) 将选择正确实现的任务委托给不同的组件。
例如,可以调用该组件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
。
我知道,这似乎是退后一步,但在某些情况下,我更愿意这样做:当业务逻辑不太复杂且不太可能改变时。