是否可以在Asp.Net Core中为默认DI设置注入范围?我的意思是例如:
services.AddSingleton<IUser, UserService>
services.AddSingleton<IUser, UserService>
并且对于第二种配置,以某种方式指定它应该仅注入HomeController。不像第一个应该注入所有其他人。是否可以使用默认DI?
假设这个注册,依赖注入容器应该如何知道哪个“单例”(当它们有两个时它不是真正的单例)它应该注入HomeController,或者一个不同的服务,当它们都只依赖于IUser
时?
依赖关系被注册的类型,在您的情况下为IUser
,是DI容器用来解决依赖关系的“关键”。因此,两个依赖于IUser
的服务将以相同的方式解决它们的依赖关系。使用单例生存期,这意味着两个服务都获得相同的实例。
服务注册通常也会被替换。因此,如果你有一个注册AddSingleton<X, Y>()
,然后有另一个AddSingleton<X, Z>()
,那么后者将取代前者。因此,所有依赖X
的服务都将获得Z
。
DI容器(包括ASP.NET Core附带的默认容器)通常支持通过依赖IEnumerable<X>
来解析所有注册。但是对于这个例子,这只意味着服务将获得Y
和Z
。
您正在寻找的最接近的是键控或命名依赖项。虽然在某些DI容器中支持这些,但它们在技术上不是依赖注入的一部分,因此通常来自许多容器的deliberately absent,包括ASP.NET Core容器。 See this answer有关这方面的更多细节以及一些想法来解决这个问题。
要回到你的用例,你应该考虑一下你在那里做了什么。如果你有UserService
的两个“单例”实例,你应该考虑为什么会这样:为什么不存在一个?如果有多重支持,为什么不将其注册为瞬态?
更重要的是,这两个实例之间可能会有什么不同?毕竟,它们都是相同实现的实例,因此他们可以做的不同。
如果您能够识别出这一点,并确认这实际上是使实例不同的话,那么也可以考虑在类型层次结构中将其拆分。如果没有这里的用例,很难解释这一点,但你应该尝试的是最终得到两个different interfaces that each do exactly what each dependent service type needs。所以HomeController
可以依靠IUserA
,其他人可以依靠IUserB
(请选择比这更好的名字)。