C# 什么';这两个StructureMap配置之间的区别是什么?

C# 什么';这两个StructureMap配置之间的区别是什么?,c#,.net-4.0,dependency-injection,structuremap,C#,.net 4.0,Dependency Injection,Structuremap,我们正在努力理解这两种配置StructureMap的方法之间的区别。我们的理解是,它们应该是相同的,但我们在初始化中的这两行之间得到不同的结果: ObjectFactory.Initialize(x => { x.For<IBusinessRelationsContext>().Use<BusinessRelationsContext>().Ctor<string>().Is(ConfigurationManager.ConnectionStri

我们正在努力理解这两种配置StructureMap的方法之间的区别。我们的理解是,它们应该是相同的,但我们在初始化中的这两行之间得到不同的结果:

ObjectFactory.Initialize(x =>
{
    x.For<IBusinessRelationsContext>().Use<BusinessRelationsContext>().Ctor<string>().Is(ConfigurationManager.ConnectionStrings["BusinessRelationsContext"].ConnectionString);
    x.For<IBusinessRelationsContext>().Use(_ => new BusinessRelationsContext(ConfigurationManager.ConnectionStrings["BusinessRelationsContext"].ConnectionString));
});
我们用来调用它的代码是:

ObjectFactory.TryGetInstance<IBusinessRelationsContext>();
ObjectFactory.TryGetInstance();
我们看到的行为差异是,包含
Ctor
的行失败,因为StructureMap失败,出现了一个202“没有为PluginFamily System.Data.Common.DbConnection定义默认实例”(我们不知道它为什么认为需要这个)。然而,如果我将这一行注释掉并使用另一行,它将如我们所期望的那样完美地工作。考虑到另一个可以工作,我怀疑我对DbConnection不需要配置的理解是正确的


因此,与其追查它为什么需要DbConnection,不如追查我的问题的答案:这两者之间有什么区别?

我认为StructureMap选择了最复杂的构造函数来尝试创建datacontext。您在那里通过Ctor调用定义的是如何使用不太复杂的构造函数定义该类的定义

所以你的定义没有错,只是StructureMap没有调用你认为它应该调用的构造函数

注意:我通常使用您的第二次调用,因为我知道将调用什么构造函数,即使您为了测试或其他目的必须添加新构造函数。

x.For<IBusinessRelationsContext>().Use(_ => new BusinessRelationsContext(ConfigurationManager.ConnectionStrings["BusinessRelationsContext"].ConnectionString));
x.For().Use(=>newBusinessRelationsContext(ConfigurationManager.ConnectionString[“BusinessRelationsContext”].ConnectionString));

所以我请了一些离线的人帮我做这件事(没想到我会在这方面有任何离线资源!),问题是正如Khalid Abuhakmeh所解释的——它选择了最复杂的(最贪婪的)

既然我们知道了问题所在,我们就可以寻找解决办法了。在我的情况下(以及这里的评论),解决方案是添加一行,如下所示:

x.SelectConstructor<IBusinessRelationsContext>(() => new BusinessRelationsContext(""));
x.SelectConstructor(()=>newBusinessRelationsContext(“”);

这有点重要,因为我们过去一直使用
.Ctor
的方法来做这件事(而且一直有效),但考虑到它开始失败(我们不知道为什么),我们需要更好地理解这一点。我们在概念上遗漏了一些东西,我不想有一个滴答作响的定时炸弹……我想我自己也看到了这一点,使用Ctor似乎不起作用。我对
Ctor
的理解正确吗?我说,“对于IBusinesRelationsContext实例,使用BusinessRelationsContext对象并使用单个字符串参数调用构造函数,然后传入
ConfigurationManager.ConnectionString[“BusinessRelationsContext”]。ConnectionString
计算为该字符串参数"? 还有什么其他的吗?有趣的是,我们使用
Ctor
的方式处理各地的其他上下文对象!因为我们的数据库太大了,所以当我们把它分成几个部分时,我们有大约20个不同的上下文,它对所有20个上下文都有效。碰巧的是,在这些特定的单元测试中,这一特定上下文失败了,而其他上下文使用
Ctor
方法可以很好地工作。(所有上下文都是从同一个模板生成的代码,所以没有区别!)这就是我对它的理解,我已经使用SM 3年多了。上一次我想做这样的事情时,我很确定我最终不得不做与你在使用中手动更新对象类似的事情。就是这样,但还有更多。我将发布解决方案,以使.Ctor方式工作!:-我向你提供了问题的答案,但我在另一个答案中发布了问题的解决方案太棒了,你终于明白了。如果你的信用是正确的,你不必给我信用。我希望人们看到正确的答案。即使这意味着我的信用较低。好吧,你的回答是对问题的正确回答。问题是,“有什么区别?”你的正确答案是“StructureMap没有调用我认为它应该调用的构造函数”,这是我之前没有考虑过的。我发布的答案是对一个明显的后续问题的回答:“我如何让它调用我认为它应该调用的构造函数?”:)我知道,StructureMap以强类型和唯一标识的方式任意选择一个构造函数,即使我的配置行显式指定,构造函数的参数。那太糟糕了!(来自一个从未开发过DI引擎的人)这不是武断的。StructureMap总是选择最贪婪的构造函数。这是有据可查的行为。您的配置行(问题中)指定了一个构造函数参数的值-它没有指定构造函数。可以指定字符串构造函数param,同时让容器自动解析任何其他参数。@Joshua:在这种情况下,我有两个同样贪婪的构造函数。两个构造函数接受一个参数。其中一个恰好接收单个字符串(我指定了一个字符串类型),而另一个接收单个EntityConnection。我们已经成功地使用了
.Ctor
方法一年半了,但是由于这个问题,我们第一次遇到了StructureMap将选择另一个构造函数的问题。两名施工人员均已使用1.5年,签名未更改。如果你不认为这是任意的,那么就解释一下这种突然的行为改变。最贪婪的人被选中的事实并不是任意的——这似乎是你所反对的。如果你对最贪婪的人有一个联系,那么是的,这将有点随意,因为它依赖于构造函数从.NET反射返回的顺序。
x.SelectConstructor<IBusinessRelationsContext>(() => new BusinessRelationsContext(""));