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

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

  1. private IServiceProvider _applicationServices;
  2. public IServiceProvider Services
  3. {
  4. get
  5. {
  6. return _applicationServices;
  7. }
  8. }

它的实例化是通过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:

  1. private readonly IServiceScopeFactory _scopeFactory;
  2. // 或者 private readonly IServiceProvider _serviceProvider;
  3. _scope = _scopeFactory.CreateScope();
    // _scope = _serviceProvider.CreateScope();
  4. _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/

asp.net core的DI框架思考以及服务实例的获取方式总结的更多相关文章

  1. 实战Asp.Net Core:DI生命周期

    title: 实战Asp.Net Core:DI生命周期 date: 2018-11-30 21:54:52 --- 1.前言 Asp.Net Core 默认支持 DI(依赖注入) 软件设计模式,那使 ...

  2. Asp.Net Core中DI的知识总结

    在asp.net core中DI的概念是由这几部分组成的: IServiceCollection,保存IServiceDescriptor实例的列表 IServiceProvider,只有一个方法Ge ...

  3. ASP.NET Core 使用 EF 框架查询数据 - ASP.NET Core 基础教程 - 简单教程,简单编程

    原文:ASP.NET Core 使用 EF 框架查询数据 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 使用 EF 框架查询数据 上一章节我们学习了如何设置 ...

  4. ASP.NET Core 配置 EF 框架服务 - ASP.NET Core 基础教程 - 简单教程,简单编程

    原文:ASP.NET Core 配置 EF 框架服务 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 配置 EF 框架服务 上一章节中我们了解了 Entity ...

  5. 在ASP.NET Core Web API中为RESTful服务增加对HAL的支持

    HAL(Hypertext Application Language,超文本应用语言)是一种RESTful API的数据格式风格,为RESTful API的设计提供了接口规范,同时也降低了客户端与服务 ...

  6. 在 asp.net core 中使用类似 Application 的服务

    在 asp.net core 中使用类似 Application 的服务 Intro 在 asp.net 中,我们可以借助 Application 来保存一些服务器端全局变量,比如说服务器端同时在线的 ...

  7. 用Scrutor来简化ASP.NET Core的DI注册

    目录 背景 Scrutor简介 Scrutor的简单使用 注册接口的实现类 注册类自身 重复注册处理策略 总结 相关文章 背景 在我们编写ASP.NET Core代码的时候,总是离不开依赖注入这东西. ...

  8. Asp.net Core基于MVC框架实现PostgreSQL操作

    简单介绍 Asp.net Core最大的价值在于跨平台.跨平台.跨平台.重要的事情说三遍.但是目前毕竟是在开发初期,虽然推出了1.0.0 正式版,但是其实好多功能还没有完善.比方说编译时的一些文件编码 ...

  9. asp.net core利用DI实现自定义用户系统,脱离ControllerBase.User

    前言 很多时候其实我们并不需要asp.net core自带的那么复杂的用户系统,基于角色,各种概念,还得用EF Core,而且在web应用中都是把信息存储到cookie中进行通讯(我不喜欢放cooki ...

随机推荐

  1. <Android基础>(三) UI开发 Part 2 ListView

    ListView 1)ListView的简单用法 2)定制ListView界面 3)提升ListView的运行效率 4)ListView的点击事件 3.5 ListView 3.5.1 ListVie ...

  2. [M$]微软提供的ProcessExplorer等系统工具集合

    https://docs.microsoft.com/en-us/sysinternals/downloads/index

  3. jmeter5.1测试dubbo接口

    dubbo接口功能介绍 客户端输入uncleyong(当然,也可以是其他字符串),服务端返回hello uncleyong 开发dubbo服务jmeter客户端 idea中创建模块dubbo_jmet ...

  4. java 11 不可修改集合API

    不可修改集合API 自 Java 9 开始,Jdk 里面为集合(List/ Set/ Map)都添加了 of 和 copyOf 方法,它们两个都用来创建不可变的集合,来看下它们的使用和区别. 示例1: ...

  5. vue 中 echart 在子组件中只显示一次的问题

    问题描述 一次项目开发过程中,需要做一些图表,用的是百度开源的 echarts. vue推荐组件化开发,所以就把每个图表封装成子组件,然后在需要用到该图表的父组件中直接使用. 实际开发中,数据肯定都是 ...

  6. HDU - 1078 FatMouse and Cheese (记忆化搜索)

    FatMouse has stored some cheese in a city. The city can be considered as a square grid of dimension ...

  7. Ajax与JSON共同使用的小实例

    实现的效果: 点击“点击”按钮,可以通过Ajax从服务器调过来相应的文档文件,而不需重新加载页面. 通过json可以将调过来的文档(String)转换为相应的json对象,从而对文档中数据进行操作. ...

  8. kubernetes云平台管理实战: 滚动升级秒级回滚(六)

    一.nginx保证有两个版本 1.查看当前容器运行nginx版本 [root@k8s-master ~]# kubectl get pod -o wide NAME READY STATUS REST ...

  9. Entity Framework入门教程(5)---EF中的持久化场景

    EF中的持久性场景 使用EF实现实体持久化(保存)到数据库有两种情况:在线场景和离线场景. 1.在线场景 在线场景中,context是同一个上下文实例(从DbContext派生),检索和保存实体都通过 ...

  10. React 记录(7)

    React文档:https://www.reactjscn.com/docs/handling-events.html 慢慢学习:对照教程文档,逐句猜解,截图 React官网:https://reac ...