获取控制器中当前的IServiceScope

dba*_*kov 6 c# dependency-injection asp.net-core asp.net-core-webapi

IServiceScope如何获取控制器中当前(每个请求)的实例?在服务中?

计划是用它来解析属于同一范围的服务。

itm*_*nus 8

在控制器中获取一个实例...

  1. 无需IHttpContextAccessorController内使用。已经有适合您的HttpContext房产了。如果你想访问HttpContext,只需

    // no need to use IHttpContextAccessor.HttpContext
    var svc = HttpContext.RequestServices.GetService<MyService>();
    
    Run Code Online (Sandbox Code Playgroud)
  2. 或者作为替代方案,直接注入IServiceProvider

    public class MyController : Controller
    {
        private IServiceProvider _sp;
        public MyController(IServiceProvider sp)
        {
            this._sp = sp;
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

    当你想要一个小范围时,你可以如下创建:

    public IActionResult MyActoin()
    {
        // create a more small scope
        using (var scope = this._sp.CreateScope())
        {
            var sp = scope.ServiceProvider;
            // now you get the services from this small scope
            var svc1 = sp.GetRequiredService<MyService1>();
            var svc2 = sp.GetRequiredService<MyService2>();
            //...
        }
        return new JsonResult("it works");
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 特别是,如果所需服务的范围恰好是请求范围,则只需将它们全部注入:

    public class MyController : Controller
    {
        private IServiceProvider _sp;
        private readonly MyService1 _service1;
        private readonly MyService2 _service2;
    
        public MyController(IServiceProvider sp, MyService1 service1, MyService2 service2,...)
        {
            this._sp = sp;
            this._service1 = service1;
            this._service2 = service2;
        }
    
    Run Code Online (Sandbox Code Playgroud)


dba*_*kov 1

一种解决方案是在控制器的构造函数中请求IHttpContextAccessor contextAccessor,然后从中解析所需的服务:

var svc = contextAccessor.HttpContext.RequestServices.GetService<MyService>();