计算器:
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);
}
}
计算器stragies:
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));
}
}
Structuremap Registry:
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实现此目的?
答案 0 :(得分: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
(open generics),然后在构造函数中实例化策略对象。
或者,您可以使用marker interfaces代替泛型,但再一次,这一切都取决于您的特定情况,并且可能是从一开始就最简单的解决方案最适合。
答案 1 :(得分:1)
一种方法是使用With
方法获取实例时定义依赖关系。
var additionStrategy = ObjectFactory
.GetNamedInstance<ICalculatorStrategy>("Addition");
var c1 = ObjectFactory.With(additionStrategy).GetInstance<CalculatorUsageOne>();
我能想到的另一种方法是在注册类型时将isntances作为构造函数参数提供。我明天可以提供一个例子。