1

这是我的解决方案中几个类的简化版本以及它们实现的接口。它们都共享一个接口,也实现了一个专用接口。

public interface ISharedContract
{
    void ImplementSharedContract();
}

public interface IConcreteOne
{
    void ImplementConcreteOne();
}

public interface IConcreteTwo
{
    void ImplementConcreteTwo();
}

public class ConcreteOne : BaseConcrete, IConcreteOne, ISharedContract
{
    public void ImplementSharedContract()
    {
        this.ImplementConcreteOne();
    }

    public void ImplementConcreteOne()
    {
    }
}

public class ConcreteTwo : BaseConcrete, IConcreteTwo, ISharedContract
{
    public void ImplementSharedContract()
    {
        this.ImplementConcreteTwo();
    }

    public void ImplementConcreteTwo()
    {
    }
}

我的 StructureMap 注册表按如下方式注册这些依赖项:

public class MyRegistry :  Registry
{
    public MyRegistry()
    {
        this.For<ISharedContract>().Use<ConcreteOne>().Named("cOne");
        this.For<ISharedContract>().Use<ConcreteTwo>().Named("cTwo");
        this.For<IConcreteOne>().Use<ConcreteOne>();
        this.For<IConcreteTwo>().Use<ConcreteTwo>();
    }
}

最后我有一个类,它在构造函数中注入这些依赖项,如下所示:

public MyDependent(ISomethingElse somethingElse, ISharedContract cOne, ISharedContract cTwo)
{
    this.collection = new List<ISharedContract>()
    {
        cOne,
        cTwo
    };
}

在运行时,我观察到 cOne 和 cTwo 都是ConcreteTwo. 如果我在 StructureMap 注册表中交换两个命名注册的顺序,则 cOne 和 cTwo 都是ConcreteOne.

这不是我第一次使用命名实例,但我之前没有观察到这一点。有什么我想念的吗?我已经检查并再次检查了传递给 Named 方法的值是否与构造函数中的参数名称相对应。

更新

这是使我的示例案例工作所需的更新的注册表项。感谢@jeremy-d-miller 提供我需要的信息:

this.For<IMyDependent>().Use<MyDependent>()
    .Ctor<ISharedContract>("cOne").Is<ConcreteOne>()
    .Ctor<ISharedContract>("cTwo").Is<ConcreteTwo>();
4

1 回答 1

2

StructureMap 在这里没有任何神奇的功能可以将您的构造函数参数名称与该类型的命名实例匹配。在这种情况下,您必须显式映射内联依赖项:http: //structuremap.github.io/registration/inline-dependencies/

在这段代码中:

this.For<ISharedContract>().Use<ConcreteOne>().Named("cOne"); this.For<ISharedContract>().Use<ConcreteTwo>().Named("cTwo");

您将默认设置ISharedContextConcreteOne,然后立即将其覆盖为ConcreteTwo。在这种情况下,最后一个获胜。当你构建你的MyDependent类时,StructureMap 只是使用自动连接来推入ISharedContext.

于 2016-03-31T13:00:55.447 回答