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 将请求的任何泛型参数传递ICalculatorCalculator打开泛型),然后在构造函数中实例化策略对象。

或者,您可以使用标记接口而不是泛型,但同样,这一切都取决于您的特定场景,并且从一开始最简单的解决方案可能最适合。

于 2011-07-04T21:01:37.727 回答
1

一种方法是在使用该方法获取实例时定义依赖关系With

var additionStrategy = ObjectFactory
                            .GetNamedInstance<ICalculatorStrategy>("Addition");
var c1 = ObjectFactory.With(additionStrategy).GetInstance<CalculatorUsageOne>();

我能想到的唯一另一种方法是在注册类型时提供实例作为构造函数参数。我明天可以提供一个例子。

于 2011-07-04T20:57:57.397 回答