使用Asp.Net Core DI的服务的配置范围

问题描述 投票:0回答:2

是否可以在Asp.Net Core中为默认DI设置注入范围?我的意思是例如:

services.AddSingleton<IUser, UserService>
services.AddSingleton<IUser, UserService>

并且对于第二种配置,以某种方式指定它应该仅注入HomeController。不像第一个应该注入所有其他人。是否可以使用默认DI?

c# .net asp.net-core dependency-injection .net-core
2个回答
0
投票

我相信你可以为某个控制器指定特殊注射。

 public void ConfigureServices(IServiceCollection services)
 {
        services.AddMvc();

        services.AddScoped<TestService>();
        services.AddTransient(ctx =>
            new HomeController(new TestService("Non-default value")));
 }

这个tutorial有更深刻的解释。

可能被视为解决方法的第二件事是注册基于名称的函数,返回不同的服务实现。我之前用过like this


0
投票

假设这个注册,依赖注入容器应该如何知道哪个“单例”(当它们有两个时它不是真正的单例)它应该注入HomeController,或者一个不同的服务,当它们都只依赖于IUser时?

依赖关系被注册的类型,在您的情况下为IUser,是DI容器用来解决依赖关系的“关键”。因此,两个依赖于IUser的服务将以相同的方式解决它们的依赖关系。使用单例生存期,这意味着两个服务都获得相同的实例。

服务注册通常也会被替换。因此,如果你有一个注册AddSingleton<X, Y>(),然后有另一个AddSingleton<X, Z>(),那么后者将取代前者。因此,所有依赖X的服务都将获得Z

DI容器(包括ASP.NET Core附带的默认容器)通常支持通过依赖IEnumerable<X>来解析所有注册。但是对于这个例子,这只意味着服务将获得YZ

您正在寻找的最接近的是键控或命名依赖项。虽然在某些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(请选择比这更好的名字)。

© www.soinside.com 2019 - 2024. All rights reserved.