应该首选哪个依赖注入生命周期?

Per*_*ert 5 c# api rest asp.net-core

对于 REST api,它在请求之间没有依赖关系并且使用 ASP.NET Core DI。

在选择最合适的方式时,我听到了相互矛盾的论点:

  • 由于内存和多线程问题,并且由于强制依赖,不应将单例注入其他生命周期,因此更喜欢瞬态然后作用域并避免单例
  • 首选单例以节省实例化对象的时间并防止打开多个连接

我知道它们的工作方式不同,但是有“首选”的生命周期吗?它是否应该从“瞬态”开始并根据需要转移到其他人身上?

是否有任何调查证明单例节省的实例化时间实际上是相关的?

Str*_*ior 5

我不会说这里有对错方法,但我会分享我的个人经验。

我已经尝试了两种方法,最终发现最好从瞬态开始,然后根据需要扩展范围。

考虑单一职责原则和变更原因。您的服务的生命周期范围可能需要更改的原因可能与您对服务实现本身所做的更改有关。当该原因发生时,您只想更改一个类。

如果您的服务需要比大多数其他服务寿命更长,您所要做的就是延长它的寿命并将工厂注入任何寿命较短的依赖项。

另一方面,如果你有一个类需要比大多数其他服务更短,你最终必须将它作为工厂注入所有更长的服务。因此,一个更改原因会影响整个代码库中的代码。

当然,这是假设您正确地做事:避免强制依赖并记住使非线程安全服务成为瞬态。我发现记住哪些服务需要长期存在并在那个方向覆盖默认值比记住哪些服务应该长期存在并以这种方式覆盖默认值容易得多。而且我发现如果不执行后者会导致更隐蔽的错误,这些错误更难以注意到并导致更大的损害。

关于性能:我没有使用 ASP.NET Core 内置 DI 框架进行性能测试,但我发现 SimpleInjector 足够快,相比之下,创建新服务实例的时间和内存开销微不足道与我的应用程序所做的其他工作(如查询数据库)。

关于防止打开多个连接:SQL Server 连接是自动汇集的,因此new SqlConnection()在请求中多次创建和处理它的成本通常是微不足道的。