StructureMap: Choose concrete type of nested dependency

╄→гoц情女王★ 提交于 2019-12-01 17:57:46

Try like this:

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>()
    );

You can nest your objects graph configurations as deep as you need. Anyway, I would think about using generics here to show the dependencies in more explicit way.

edit about generics:

Whether using generics is a good idea here depends from your scenario. If you didn't specified the concrete dependencies for your CalculatorUsages on purpose and that's your goal to have it strategy-agnostic, your solution seems to be the best.

But if you just need to have common implementation of Calculator in "middle layer", you can specify Calculator's dependency in generic parameter to make it explicit. Maybe it's not the best use case here, but it can go somehow like this:

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

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

and register it like this:

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

This will tell StructureMap to pass any generic parameter for requested ICalculator to Calculator (open generics), which then instantiates the strategy objects in constructor.

Alternatively, you can use marker interfaces instead of generics, but once again, it all depends from your particular scenario and it may be that the simplest solution from very beginning fits best.

One method is to define the dependency when getting an instance using the With method.

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

The only other way I can think of is providing the isntances as constructor arguments when registering the types. I can provide an example tomorrow.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!