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

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

在下面的代码中(来自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>();
}

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

它与仅在 Startup.cs 中添加 services.AddScope<Mediator>(); 然后注入 mediator.

有何不同
// Startup.cs
public void ConfigureServices(IServiceCollection services)
{
    // services.AddSingleton<Mediator>(); 
    services.AddScope<Mediator>();

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

因此它节省了一些样板文件,但也使依赖关系不那么明确。

旁注,Microsoft 建议优先使用注入而不是 RequestServices

The services available within an ASP.NET Core request from HttpContext are exposed through the HttpContext.RequestServices collection.

Request Services represent the services configured and requested as part of the app. When the objects specify dependencies, these are satisfied by the types found in RequestServices, not ApplicationServices.

Generally, the app shouldn't use these properties directly. Instead, request the types that classes require via class constructors and allow the framework inject the dependencies. This yields classes that are easier to test.

Note

Prefer requesting dependencies as constructor parameters to accessing the RequestServices collection.

Microsoft docs