结果将是相同的,但第二个示例执行了一个额外的步骤。它真的很小。但更简单的语法更好。
第一个例子说,当需要 时ISomeClass
,用 来满足它SomeClass
。如果已创建实例,请使用它。如果没有,请创建一个实例。
第二个例子说当需要时ISomeClass
,通过调用一个匿名函数来实现它,该函数将返回一个实现ISomeClass
。该函数解析并返回SomeClass
.
考虑到幕后正在进行的大量工作,再调用一个匿名函数并不会产生太大的影响。
更大的担忧是更复杂的方法如何混淆其他开发人员并产生问题。这不是假设。我已经看到了,结果不是很好。
后面的开发人员可能不了解 IoC 容器应该如何工作,他们所能做的就是按照您的示例进行操作,直到他们理解为止。因此,树立正确的榜样很重要,否则他们可能会完全错过重点。我见过这样的工厂方法:
this.For<ISomeClass>()
.Use(c=> new SomeClass(
c.GetInstance<ISomethingElse>(),
c.GetInstance<ISomeOtherThing>(),
c.GetInstance<ITenMoreOfThese>()
));
然后他们开始像这样创建对象,解析实例,并使用 DI 注册将实例注入对象。当然,偶尔会有这样做的正当理由。但是它会污染你的 IoC 代码,直到改变一个类的依赖关系变得很痛苦,这是容器应该解决的问题之一。
这实际上滚雪球更多。现在开发人员不想接触越来越脆弱和令人困惑的 IoC 代码,因此他们停止创建新类,开始将新功能塞进现有方法中,并且从不重构任何东西。IoC 应该使重构和更小的类和接口变得更容易,但最终却让这一切变得更加困难。这会导致各种新的代码异味和腐烂。
所以我推荐“无破窗”方法——使用遵循 IoC 原始意图的最简单语法——尽可能为接口指定实现类型,而不是解析并返回实现的函数。