5

電卓:

public interface ICalculator
{
    int Calculate(int a, int b);
}

public class Calculator : ICalculator
{
    private readonly ICalculatorStrategy _calculatorStrategy;

    public Calculator(ICalculatorStrategy calculatorStrategy)
    {
        _calculatorStrategy = calculatorStrategy;
    }

    public int Calculate(int a, int b)
    {
        return _calculatorStrategy.Calculate(a, b);
    }
}

電卓戦略:

public interface ICalculatorStrategy
{
    int Calculate(int a, int b);
}

public class AdditionCalculator : ICalculatorStrategy
{
    public int Calculate(int a, int b)
    {
        return a + b;
    }
}

public class MultiplyCalculator : ICalculatorStrategy
{
    public int Calculate(int a, int b)
    {
        return a * b;
    }
}

電卓の使用法:

public class CalculatorUsageOne
{
    private readonly ICalculator _calculator;

    public CalculatorUsageOne(ICalculator calculator)
    {
        _calculator = calculator;
    }

    public void Process()
    {
        Console.WriteLine(_calculator.Calculate(6, 5));
    }
}

public class CalculatorUsageTwo
{
    private readonly ICalculator _calculator;

    public CalculatorUsageTwo(ICalculator calculator)
    {
        _calculator = calculator;
    }

    public void Process()
    {
        Console.WriteLine(_calculator.Calculate(6, 5));
    }
}

ストラクチャマップ レジストリ:

public class DependencyRegistry : Registry
{
    public DependencyRegistry()
    {
        For<ICalculatorStrategy>().Use<AdditionCalculator>().Named("Addition");
        For<ICalculatorStrategy>().Use<MultiplyCalculator>().Named("Multiply");
        For<ICalculator>().Use<Calculator.Calculator>();
    }
}

CalculatorUsageOne の場合、数値を追加します ( AdditionCalculatorを使用します)。CalculatorUsageTwo の場合、数値を乗算します ( MultiplyCalculatorを使用します)。

StructureMap でこれを達成するにはどうすればよいですか?

4

2 に答える 2

4

このようにしてみてください:

For<CalculatorUsageOne>().Use<CalculatorUsageOne>()
    .Ctor<ICalculator>().Is<Calculator.Calculator>(
        x => x.Ctor<ICalculatorStrategy>().Is<AdditionCalculator>()
    );
For<CalculatorUsageTwo>().Use<CalculatorUsageTwo>()
    .Ctor<ICalculator>().Is<Calculator.Calculator>(
        x => x.Ctor<ICalculatorStrategy>().Is<MultiplyCalculator>()
    );

オブジェクトのグラフ構成を必要なだけ深くネストできます。とにかく、ここでジェネリックを使用して、依存関係をより明確に示すことを考えます。

ジェネリックについて編集:

ここでジェネリックを使用することが良い考えであるかどうかは、シナリオによって異なります。意図的に具体的な依存関係を指定してCalculatorUsagesおらず、それを戦略に依存しないようにすることが目標である場合は、ソリューションが最適であるように思われます。

Calculatorただし、「中間層」での一般的な実装が必要な場合はCalculator、ジェネリックパラメータでの依存関係を指定して明示的にすることができます。ここでは最適なユースケースではないかもしれませんが、どういうわけか次のようになります。

public class CalculatorUsageOne
{
    public CalculatorUsageOne(ICalculator<AdditionCalculator> calculator)
    {
        // ...
    }
}

public class Calculator<T> where T : ICalculatorStrategy
{
    public Calculator(T strategy)
    {
        // ...
    }
}

次のように登録します。

For(typeof(ICalculator<>).Use(typeof(Calculator<>);

これにより、StructureMapは、要求ICalculatorされたジェネリックパラメーターCalculatorジェネリックを開く)を渡すように指示されます。これにより、コンストラクターでストラテジーオブジェクトがインスタンス化されます。

または、ジェネリックの代わりにマーカーインターフェイスを使用することもできますが、これもすべて特定のシナリオに依存するため、最初から最も単純なソリューションが最適である可能性があります。

于 2011-07-04T21:01:37.727 に答える