Spring.net IoC - Vary按州注入类

时间:2012-06-26 02:50:49

标签: dependency-injection spring.net

我正在尝试注入依赖于传入状态的依赖项。例如,如果状态是Wisconsin,我想注入一个类,但如果它是Illinois,我想要另一个。它不是1对1,而是7个状态为1,3个为另一个。

Spring.net中是否有一种方法可以在config xml中检查要检查的值列表?

1 个答案:

答案 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();
    }
}

Spring.Net可配置示例

如果您希望能够在弹簧配置中配置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" />