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;
}
}
它的实例化是通过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/
asp.net core的DI框架思考以及服务实例的获取方式总结的更多相关文章
- 实战Asp.Net Core:DI生命周期
title: 实战Asp.Net Core:DI生命周期 date: 2018-11-30 21:54:52 --- 1.前言 Asp.Net Core 默认支持 DI(依赖注入) 软件设计模式,那使 ...
- Asp.Net Core中DI的知识总结
在asp.net core中DI的概念是由这几部分组成的: IServiceCollection,保存IServiceDescriptor实例的列表 IServiceProvider,只有一个方法Ge ...
- ASP.NET Core 使用 EF 框架查询数据 - ASP.NET Core 基础教程 - 简单教程,简单编程
原文:ASP.NET Core 使用 EF 框架查询数据 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 使用 EF 框架查询数据 上一章节我们学习了如何设置 ...
- ASP.NET Core 配置 EF 框架服务 - ASP.NET Core 基础教程 - 简单教程,简单编程
原文:ASP.NET Core 配置 EF 框架服务 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 配置 EF 框架服务 上一章节中我们了解了 Entity ...
- 在ASP.NET Core Web API中为RESTful服务增加对HAL的支持
HAL(Hypertext Application Language,超文本应用语言)是一种RESTful API的数据格式风格,为RESTful API的设计提供了接口规范,同时也降低了客户端与服务 ...
- 在 asp.net core 中使用类似 Application 的服务
在 asp.net core 中使用类似 Application 的服务 Intro 在 asp.net 中,我们可以借助 Application 来保存一些服务器端全局变量,比如说服务器端同时在线的 ...
- 用Scrutor来简化ASP.NET Core的DI注册
目录 背景 Scrutor简介 Scrutor的简单使用 注册接口的实现类 注册类自身 重复注册处理策略 总结 相关文章 背景 在我们编写ASP.NET Core代码的时候,总是离不开依赖注入这东西. ...
- Asp.net Core基于MVC框架实现PostgreSQL操作
简单介绍 Asp.net Core最大的价值在于跨平台.跨平台.跨平台.重要的事情说三遍.但是目前毕竟是在开发初期,虽然推出了1.0.0 正式版,但是其实好多功能还没有完善.比方说编译时的一些文件编码 ...
- asp.net core利用DI实现自定义用户系统,脱离ControllerBase.User
前言 很多时候其实我们并不需要asp.net core自带的那么复杂的用户系统,基于角色,各种概念,还得用EF Core,而且在web应用中都是把信息存储到cookie中进行通讯(我不喜欢放cooki ...
随机推荐
- logstash/conf.d文件编写
logstash-01.conf input { beats { port => 5044 host => "0.0.0.0" type => "log ...
- django restframework permission
与 authentication 和 throttling 一起,permission 决定是应该接受还是拒绝访问请求.权限检查总是在视图的最开始处运行,在任何其他代码被允许进行之前.权限检查通常会使 ...
- Python爬虫之二
1)什么叫做URL url是统一资源定位符,对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址.互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及 ...
- docker的基础命令
详细命令参考http://www.runoob.com/docker/docker-command-manual.html
- 和CISSP并肩的信息安全认证国际注册信息安全经理CISM
众所周知,信息安全认证界有一个扛把子的证书叫CISSP(国际信息安全专家认证),一般拥有CISSP证书的小哥哥还会选择考取另一个认证,这就是今天给大家介绍的CISM(国际注册信息安全经理).CISM是 ...
- SpringCloud笔记三:Eureka服务注册与发现
目录 什么是Eureka? Eureka注册的三大步 第一步,引用Maven 第二步,配置yml 第三步,开启Eureka注解 新建Eureka子项目 把provider子项目变成服务端 Eureka ...
- MS SQL Server 数据库连接字符串详解
MS SQL Server 数据库连接字符串详解 原地址:http://blog.csdn.net/jhhja/article/details/6096565 问题 : 超时时间已到.在从池中获取连接 ...
- Entity Framework入门教程(19)---EF中使用事务
EF中使用事务 这节介绍EF6中事务的使用.EF core中事务的使用方式和EF6中一模一样. 1.EF中的默认的事务 默认情况下,当我们执行一个SaveChanges()方法时就会新建了一个事务,然 ...
- DirectX11--深入理解HLSL常量缓冲区打包规则
HLSL常量缓冲区打包规则 DirectX11 With Windows SDK完整目录 欢迎加入QQ群: 727623616 可以一起探讨DX11,以及有什么问题也可以在这里汇报. 尽管打包规则并不 ...
- luogu 4042 有后效性的dp
存在有后效性的dp,但转移方程 f[i] = min( f[i], s[i] + sigma f[j] ( j 是后效点) ) 每次建当前点和 转移点的边 e1, 某点和其会影响的点 e2 spfa ...