我有一个具有以下结构的课程
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只是一个枚举类型,在整个实例中永远不会被更改。
答案 0 :(得分:2)
由于一个简单的原因,无法指示StructureMap这样做:
measureType
属性。IMeasureService
依赖关系,因为它是readonly
(也应该是private
)因此,这个问题的解决方案更多地与类的设计有关,而不是与StructureMap有关。
以下是我在这种情况下通常会选择的解决方案:
IMeasureService
实施的任务委托给不同的组件。例如,该组件可以被称为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()
方法进行适当调用,以便正确解析所需的服务。
现在,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配置。容器将能够正确解决所有问题。
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>();
IMeasureService
实现者中的逻辑不是很复杂,可以考虑将它放在一个类中,并根据measureType
对象的Measure
执行不同的操作(你已经有权访问)。我知道,这似乎是后退一步,但在某些情况下,我更愿意这样做:当业务逻辑不是过于复杂而且不太可能改变时。