我正在尝试注入因传入的州而异的依赖项。例如,如果州是威斯康星州,我想注入一个类,但如果是伊利诺伊州,我想要另一个。这不是 1 对 1,而是 7 个状态为一个,3 个为另一个。
Spring.net 中有没有一种方法可以在配置 xml 中检查值列表?
我正在尝试注入因传入的州而异的依赖项。例如,如果州是威斯康星州,我想注入一个类,但如果是伊利诺伊州,我想要另一个。这不是 1 对 1,而是 7 个状态为一个,3 个为另一个。
Spring.net 中有没有一种方法可以在配置 xml 中检查值列表?
这是.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
在你的 spring 配置中配置你的,你可以引入一个LookupStateAlgorithmFactory
. 此示例假设您IStateAlgorithm
的 s 是无状态的,并且可以在消费者之间共享:
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" />