HttpContext.RequestServices.GetService<T>() vs services.AddScope<T>()?

ca9*_*3d9 5 c# dependency-injection asp.net-core

在以下代码(来自https://github.com/JasonGT/NorthwindTraders/blob/master/Src/WebUI/Controllers/BaseController.cs)中,它是所有控制器继承的基础控件。

[ApiController]
[Route("api/[controller]/[action]")]
public abstract class BaseController : ControllerBase
{
    private IMediator _mediator;

    protected IMediator Mediator => _mediator ??= HttpContext.RequestServices.GetService<IMediator>();
}
Run Code Online (Sandbox Code Playgroud)

然后子类控制器只使用 的属性Mediator

它是如何从刚刚加入不同services.AddScope<Mediator>();Startup.cs,然后注入mediator

// Startup.cs
public void ConfigureServices(IServiceCollection services)
{
    // services.AddSingleton<Mediator>(); 
    services.AddScope<Mediator>();
Run Code Online (Sandbox Code Playgroud)

Jul*_*ian 8

不同的是,你不需要注入IMediator到BaseController的构造函数对BaseController的所有子类。

所以它节省了一些样板,但也使依赖关系不那么明确。

旁注,微软建议更喜欢注入 RequestServices

来自 HttpContext 的 ASP.NET Core 请求中可用的服务通过 HttpContext.RequestServices 集合公开。

请求服务代表作为应用程序的一部分配置和请求的服务。当对象指定依赖项时,这些依赖项由 RequestServices 中找到的类型满足,而不是 ApplicationServices。

通常,应用程序不应直接使用这些属性。相反,通过类构造函数请求类需要的类型,并允许框架注入依赖项。这产生了更容易测试的类。

笔记

更喜欢将请求依赖项作为构造函数参数来访问 RequestServices 集合。

请参阅Microsoft 文档