• asp.net core的DI框架思考以及服务实例的获取方式总结


    转载请注明出处: https://home.cnblogs.com/u/zhiyong-ITNote/

    整个asp.net core管道从WebHostBuilder到WebHost到后续请求的类中,都是使用一个ServicesCollection。WebHostBuilder类中注册的服务,以及后续用户在Startup类的ConfigureServices方法中注入的服务都是在这个集成在这个ServicesCollection中。
    根ServiceProvider: WebHost类中的属性Services返回的ServiceProvider

    private IServiceProvider _applicationServices;
    public IServiceProvider Services
    {
    get
    {
    return _applicationServices;
    }
    }
    View Code

    它的实例化是通过IServicesCollection接口的拓展方法BuilderServiceProvider()实例化出来的。此时的实例化也是基于该ServicesCollection中注册的服务。它的生命周期是应用程序从创建到结束的期间。也就是整个aspnet core整个管道的生命周期。asp.net core的DI框架中服务的注册和服务实例化就是从这里开始的,贯彻到整个管道中....
    每次请求所使用的ServiceProvider:
    该ServiceProvider的生命周期在asp.net core中的定义是scope,即服务范围——其实就是每一次的web请求。这也是aspnet core的DI框架三大生命周期中“Scope”含义:指的是针对每个HTTP请求的上下文,也就是服务范围的生命周期与每个请求上下文绑定在一起。管道总是会创建一个新的ServiceProvider来提供处理每个请求所需的服务,并且这个ServiceProvider将在每次请求处理完成之后被自动回收掉。这样一个ServiceProvider被创建之后直接保存到当前的HTTP上下文中,我们可以利用HttpContext如下所示的RequestServices属性得到这个ServiceProvider。

    根ServiceProvider的创建是在WebHostBuilder以及WebHost中,也就是aspnet core管道的创建初始时。终于aspnet core管道结束时。

    非根ServiceProvider的创建是在一个中间件中,随后写入HttpContext中,也就是请求上下文。RequestServiceFeature类负责创建非根ServiceProvider:

    private readonly IServiceScopeFactory _scopeFactory;
    // 或者 private readonly IServiceProvider _serviceProvider;
    _scope
    = _scopeFactory.CreateScope();
    // _scope = _serviceProvider.CreateScope(); _requestServices
    = _scope.ServiceProvider;

    是不是很眼熟?也就是我们平常创建一个新的scope的ServiceProvider的方式。对于IServiceScopeFactory接口,我之前描述过,请看《asp.net core 依赖注入实现全过程粗略剖析(3)》。如此就知道CreateScope方法的设计了。它就是为了创建一个特定范围的ServiceProvider——初始的设计原则应该是为了在每个请求中实现一个特定的ServiceProvider。

    如何创建一个ServiceProvider:
    1、调用IServicesCollection接口的BuilderServiceProvider方法,该方法创建的是一个根ServiceProvider。
    2、调用IServiceProvider接口的CreateScope随后调用ServiceProvider属性。该方法创建的是一个特定范围的ServiceProvider。

    总结一下aspnet core获取注册服务的实例如下:

    IServiceProvider.CreateScope()
    IServiceProvider.GetRequestService<IServiceScopeFactory>
    HttpContext.RequestServices.GetService<>
    IApplicationBuilder.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope())

    IWebHost.Services.GetService(typeof(IServiceScopeFactory))

    疑惑:
    这个疑惑我并没有去写代码实践,只是看了一篇博客自己思考了下。原博客<ASP.NET Core 新建线程中使用依赖注入的问题>.即使新开了线程,应该也是共用根ServiceProvider,根ServiceProvider应该不会在新线程中被销毁了。

    参考:

    ASP.NET Core中如影随形的”依赖注入”[上]: 从两个不同的ServiceProvider说起

    蒋金楠老师的博客,每次读都有不同的收获,如果你想要探索底层的原理,那么蒋老师的博客值得深看,多看

    转载请注明出处: https://home.cnblogs.com/u/zhiyong-ITNote/

  • 相关阅读:
    MINA简单的介绍
    java classloader详解
    nginx 和 tomcat 组合搭建后端负载均衡
    nginx主要配置
    Mysql知识汇总笔记
    gradle 构建java工程
    决策树
    如何使用hadoop RPC机制
    PowerPoint插入公式快捷键
    C++基础
  • 原文地址:https://www.cnblogs.com/zhiyong-ITNote/p/9613801.html
Copyright © 2020-2023  润新知