1

我正在尝试注入因传入的州而异的依赖项。例如,如果州是威斯康星州,我想注入一个类,但如果是伊利诺伊州,我想要另一个。这不是 1 对 1,而是 7 个状态为一个,3 个为另一个。

Spring.net 中有没有一种方法可以在配置 xml 中检查值列表?

4

1 回答 1

3

这是.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在你的 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" />
于 2012-06-26T07:54:26.420 回答