我正在尝试注入依赖于传入状态的依赖项。例如,如果状态是Wisconsin,我想注入一个类,但如果它是Illinois,我想要另一个。它不是1对1,而是7个状态为1,3个为另一个。
Spring.net中是否有一种方法可以在config xml中检查要检查的值列表?
答案 0 :(得分:3)
这是本书Dependency Injection in .NET的第6.1章“将运行时值映射到抽象”的主题。解决方案建议使用Abstract Factory
。您的抽象工厂可能如下所示:
public interface IStateAlgorithmFactory
{
IStateAlgorithm Create(string state);
}
将此工厂注入您的消费者,该消费者知道要处理哪个州。要获得IStateAlgorithm
他的消费者,请拨打y
alg = _factory.Create("Illnois");
或者,如果需要完全配置控制,可以创建一个简单的工厂,将状态名称映射到Spring容器管理的实例。
我想你有几个实现某个IStateAlgorithm
的类:
public interface IStateAlgorithm
{
string ProcessState(string stateName);
}
public class EchoingStateAlgorithm : IStateAlgorithm
{
public string ProcessState(string stateName)
{
return stateName;
}
}
public class ReverseEchoingStateAlgorithm : IStateAlgorithm
{
public string ProcessState(string stateName)
{
return new string(stateName.Reverse().ToArray());
}
}
并且有一个Consumer
需要根据运行时值选择算法。消费者可以注入工厂,从中可以检索所需的算法:
public class Consumer
{
private readonly IStateAlgorithmFactory _factory;
public Consumer(IStateAlgorithmFactory factory)
{
_factory = factory;
}
public string Process(string state)
{
var alg = _factory.Create(state);
return alg.ProcessState(state);
}
}
简单的工厂实现只需打开状态值,使用if或查看内部列表:
public interface IStateAlgorithmFactory
{
IStateAlgorithm Create(string state);
}
public class StateAlgorithmFactory : IStateAlgorithmFactory
{
private string[] _reverseStates = new[] {"Wisconsin", "Alaska"};
public IStateAlgorithm Create(string state)
{
if(_reverseStates.Contains(state))
return new ReverseEchoingStateAlgorithm();
return new EchoingStateAlgorithm();
}
}
如果您希望能够在弹簧配置中配置IStateAlgorithm
,可以引入LookupStateAlgorithmFactory
。此示例假定您的IStateAlgorithm
是无状态的,可以在消费者之间共享:
public class LookupStateAlgorithmFactory : IStateAlgorithmFactory
{
private readonly IDictionary<string, IStateAlgorithm> _stateToAlgorithmMap;
private readonly IStateAlgorithm _defaultAlgorithm;
public LookupStateAlgorithmFactory(IDictionary<string, IStateAlgorithm> stateToAlgorithmMap,
IStateAlgorithm defaultAlgorithm)
{
_stateToAlgorithmMap = stateToAlgorithmMap;
_defaultAlgorithm = defaultAlgorithm;
}
public IStateAlgorithm Create(string state)
{
IStateAlgorithm alg;
if (!_stateToAlgorithmMap.TryGetValue(state, out alg))
alg = _defaultAlgorithm;
return alg;
}
}
xml配置可以是:
<object id="lookupFactory"
type="LookupStateAlgorithmFactory, MyAssembly">
<constructor-arg ref="echo" />
<constructor-arg>
<dictionary key-type="string" value-type="IStateAlgorithm, MyAssembly">
<entry key="Alaska" value-ref="reverseEcho"/>
<entry key="Wisconsin" value-ref="reverseEcho"/>
</dictionary>
</constructor-arg>
</object>
<object id="echo" type="EchoingStateAlgorithm, MyAssembly" />
<object id="reverseEcho" type="ReverseEchoingStateAlgorithm, MyAssembly" />