1

渡された州によって異なる依存関係を注入しようとしています。たとえば、州がウィスコンシンの場合は 1 つのクラスを注入しますが、イリノイの場合は別のクラスを注入します。1 対 1 ではなく、1 つは 7 州、もう 1 つは 3 州です。

Spring.net に値のリストを設定 xml で確認する方法はありますか?

4

1 に答える 1

3

これは、ブックDependency Injection in .NETの第 6.1 章「Mapping runtime values to abstractions」の主題です。提案された解決策は、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 構成可能な例

Spring 構成でを構成できるようにしたい場合はIStateAlgorithmLookupStateAlgorithmFactory. 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" />
于 2012-06-26T07:54:26.420 に答える