asp.net core 6+中获取IServiceProvider的几种途径,以及之间的区别
获取IServiceProvider实例的几种方法
-
通过构造函数注入(Constructor Injection):
public class MyController : ControllerBase { private readonly IServiceProvider _serviceProvider; public MyController(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider; } }
-
通过
builder.Services
的BuildServiceProvider
方法获取:var serviceProvider = builder.Services.BuildServiceProvider();
-
通过
WebApplication
实例获取:WebApplication app = builder.Build(); var serviceProvider = app.Services;
-
通过HttpContext获取:
public class MyController : ControllerBase { private readonly IHttpContextAccessor _httpContextAccessor; public MyController(IHttpContextAccessor httpContextAccessor) { _httpContextAccessor = httpContextAccessor; } public IActionResult Get() { var serviceProvider = _httpContextAccessor.HttpContext?.RequestServices; Return Ok(); } }
几种方式之间的区别
特别是通过WebApplication
获取的方式
通过WebApplication
实例获取的serviceProvider
,其作用域是跟随WebApplication
的生命周期,及程序的生命周期,其可以解析到Singleton
生命周期的服务,但是如果服务注册为Scoped,就会报错Cannot resolve scoped service from root provider
,会引发服务的范围检查。
但是可以通过CreateScope
方法,来获取带范围的serviceProvider
,然后可正常获取到Scoped
生命周期的服务。
using (var serviceScope = app.Services.CreateScope())
{
var serviceProvider = serviceScope.ServiceProvider;
var repository = serviceProvider.GetService<IRepository<SysUser>>();
}