StructureMap 4,命名实例未按预期工作

时间:2016-03-31 09:00:56

标签: asp.net inversion-of-control structuremap structuremap4

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

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

1 个答案:

答案 0 :(得分:2)

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

在此代码中:

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

您将默认ISharedContext设置为ConcreteOne,然后立即将其覆盖为ConcreteTwo。在这种情况下,最后一个获胜。在构建MyDependent类时,StructureMap只是使用自动布线来推送ISharedContext的默认实例。