C# StructureMap中的这两个注册表项相同吗?

C# StructureMap中的这两个注册表项相同吗?,c#,structuremap,structuremap4,C#,Structuremap,Structuremap4,我想注册一个对应接口的单例类。 我找到了两种不同的方法来实现这一点: 备选案文1: this.For<ISomeClass>() .Use<SomeClass>() .Singleton(); this.For() .Use() .Singleton(); 备选案文2: this.For<ISomeClass>() .Use(c=>c.GetInstance<SomeClass>()) .Singleton

我想注册一个对应接口的单例类。 我找到了两种不同的方法来实现这一点:

备选案文1:

this.For<ISomeClass>()
    .Use<SomeClass>()
    .Singleton();
this.For()
.Use()
.Singleton();
备选案文2:

this.For<ISomeClass>()
    .Use(c=>c.GetInstance<SomeClass>())
    .Singleton();
this.ForConcreteType<SomeClass>()
    .Configure
    .Singleton();
this.For()
.Use(c=>c.GetInstance())
.Singleton();
这个.ForConcreteType()
.配置
.Singleton();

那么这两个电话是相同的还是有区别呢?显然,选项1由于其简洁性更为可取。

结果将是相同的,但第二个示例执行了额外的步骤。它真的很小。但是语法越简单越好

第一个例子说,当需要
isomoclass
时,用
SomeClass
来实现它。如果已创建实例,请使用它。如果不是,则创建一个实例

第二个例子说,当需要
isomoclass
时,通过调用一个匿名函数来实现它,该函数将返回
isomoclass
的实现。该函数解析并返回
SomeClass
的实例

考虑到幕后正在进行的大量工作,再调用一个匿名函数不会有多大区别

更大的担忧是,更复杂的方法如何会混淆其他开发人员并造成问题。这不是假设。我看到了,结果并不好

您后面的开发人员可能不理解IoC容器应该如何工作,他们所能做的就是遵循您的示例,直到他们理解为止。因此,树立正确的榜样很重要,否则他们可能会完全失去重点。我见过这样的工厂方法:

this.For<ISomeClass>()
    .Use(c=> new SomeClass(
        c.GetInstance<ISomethingElse>(), 
        c.GetInstance<ISomeOtherThing>(),
        c.GetInstance<ITenMoreOfThese>()
));
this.For()
.使用(c=>newsomeclass(
c、 GetInstance(),
c、 GetInstance(),
c、 GetInstance()
));
然后他们开始创建这样的对象,解析实例,并使用DI注册将实例注入到对象中。当然,偶尔会有正当的理由这样做。但是它会污染你的IoC代码,直到改变一个类的依赖关系是一件痛苦的事情,这是容器应该解决的问题之一

那实际上是雪球更多。现在,开发人员不想触及日益脆弱和混乱的IoC代码,因此他们停止创建新类,开始将新功能塞进现有方法中,并且从不重构任何东西。IoC应该使重构和更小的类和接口变得更容易,但最终却使这一切变得更加困难。这会导致各种新代码的气味和腐烂


因此,我建议采用“不破坏窗口”的方法——使用符合IoC初衷的最简单语法——尽可能为接口指定实现类型,而不是解析并返回实现的函数。

回答得好!感谢您在使用DI容器时,不仅仅是说“它是一样的”,而是对您的体验提供有价值的反馈。非常感谢@不客气。愿它能让你和其他许多人重获生命。