Net6 DI源码分析Part1 ServiceCollection、ServiceDescriptor、ServiceLifetime、IServiceProvider
ServiceCollection、ServiceDescriptor、ServiceLifetime、IServiceProvider
Microsoft.Extensions.DependencyInjection.Abstractions
Microsoft.Extensions.DependencyInjection
基础使用方式
class Car : ICar { }
interface ICar { }
IServiceCollection services = new ServiceCollection();
ServiceDescriptor transientService = new ServiceDescriptor(typeof(ICar), typeof(Car), ServiceLifetime.Transient);
services.Add(transientService);
services.AddTransient<ICar, Car>();
var serviceProvider = services.BuildServiceProvider();
var car = serviceProvider.GetService(typeof(ICar));
IServiceCollection
存放服务注册的集合
ServiceCollection
它是对IServiceCollection接口的默认实现,
核心属性private readonly List<ServiceDescriptor> _descriptors = new List<ServiceDescriptor>();可以说是对List的一个包装类。
ServiceLifetime
用于描述服务声明周期的枚举 Singleton、Scoped、Transient
ServiceDescriptor
用于描述服务的注册信息
属性,后三个为提供的的服务实际类有关。
ServiceType服务类型Lifetime生命周期Type ImplementationTypeFunc<IServiceProvider,object> ImplementationFactoryobject ImplementationInstance
它还提供了一系列静态方法供用于创建ServiceDescriptor
- ServiceDescriptor.Transient
transientService = ServiceDescriptor.Transient(typeof(ICar), typeof(Car)); - ServiceDescriptor Describe
例如ServiceDescriptor.Transient
transientService = ServiceDescriptor.Describe(typeof(ICar), typeof(Car), ServiceLifetime.Transient);
多数情况下是使用
ServiceCollectionServiceExtensions为IServiceCollection扩展的一系列方法添加服务到IServiceCollection集合。
ServiceCollectionServiceExtensions
作为IServiceCollection提供了一系列添加服务注册信息到IServiceCollection集合集合内,内部基本都是创建对应的ServiceDescriptor然后调用IServiceCollection.Add方法添加到集合内。
IServiceProviderFactory
IServiceProvider的工厂接口默认实现为DefaultServiceProviderFactory
DefaultServiceProviderFactory
IServiceProvider的工厂类
构造函数
public DefaultServiceProviderFactory() : this(ServiceProviderOptions.Default)public DefaultServiceProviderFactory(ServiceProviderOptions options)
两个方法public IServiceCollection CreateBuilder(IServiceCollection services)public IServiceProvider CreateServiceProvider(IServiceCollection containerBuilder)它的内部CreateServiceProvider也是调用的ServiceCollectionContainerBuilderExtensions提供的扩展方法。
ServiceCollectionContainerBuilderExtensions
对IServiceCollection的扩展作用就是创建IServiceProvider例如提供了BuildServiceProvider
IServiceProvider
仅有的一个方法为用于获取服务。object? GetService(Type serviceType);ServiceProvider是它的默认实现ServiceProvider`
ServiceProviderOptions
ValidateScopes验证服务之前的Scopes依赖:例如 Singleton 服务依赖另一个Scoped服务,那么这个Scoped服务实例将被一个Singleton服务实例所引用,这时候此Scoped服务实例成了一个Singleton服务实例,如果设置为TrueServiceProvider的构造方法内会创建一个CallSiteValidator对象给自己的_callSiteValidator属性。 验证动作会在当Provider获取到CallSiteSerivce后对其进行验证。ValidateOnBuildIServiceProvider对象被构建的时候会检验提供的每个ServiceDescriptor 的有效性 例如注册的Car没有一个可以用的构造函数class Car : ICar { private Car() { } }的情况 。如果设置为True此时在buildServicePrivate时会抛出异常,否则需要等GetService时才会抛出异常。这是因为这个验证是在CallSiteFactory.GetCallSite动作里面做的,当设置为true是 也只是在ServiceProvider构造函数内调用了ValidateService方法该方法循环调用CallSiteFactory.GetCallSite(ServiceDescriptor serviceDescriptor, CallSiteChain callSiteChain),也就是说把,ServiceCallSite的创建动作提前。注意GetCallSite是个重载方法。具体区别会写在CallSiteFactory章节
Net6 DI源码分析Part1 ServiceCollection、ServiceDescriptor、ServiceLifetime、IServiceProvider的更多相关文章
- Net6 DI源码分析Part5 在Kestrel内Di Scope生命周期是如何根据请求走的?
Net6 DI源码分析Part5 在Kestrel内Di Scope生命周期是如何根据请求走的? 在asp.net core中的DI生命周期有一个Scoped是根据请求走的,也就是说在处理一次请求时, ...
- Net6 DI源码分析Part4 CallSiteFactory ServiceCallSite
Net6 CallSiteFactory ServiceCallSite, CallSiteChain abstract class ServiceCallSite ServiceCallSite是个 ...
- Net6 DI源码分析Part2 Engine,ServiceProvider
ServiceProvider ServiceProvider是对IServiceProvider实现,它有一个internal的访问修饰符描述的构造,并需要两个参数IServiceCollectio ...
- Net6 DI源码分析Part3 CallSiteRuntimeResolver,CallSiteVisitor
CallSiteRuntimeResolver CallSiteRuntimeResolver是实现了CallSiteVisitor之一. 提供的方法主要分三个部分 自有成员方法 Resolve提供服 ...
- Net6 Configuration & Options 源码分析 Part1
Net6 Configuration & Options 源码分析 Part1 在Net6中配置系统一共由两个部分组成Options 模型与配置系统.它们是两个完全独立的系统. 第一部分主要记 ...
- 小白都能看懂的 Spring 源码揭秘之依赖注入(DI)源码分析
目录 前言 依赖注入的入口方法 依赖注入流程分析 AbstractBeanFactory#getBean AbstractBeanFactory#doGetBean AbstractAutowireC ...
- Android事件分发机制源码分析
Android事件分发机制源码分析 Android事件分发机制源码分析 Part1事件来源以及传递顺序 Activity分发事件源码 PhoneWindow分发事件源码 小结 Part2ViewGro ...
- Net6 Configuration & Options 源码分析 Part2 Options
Net6 Configuration & Options 源码分析 Part2 Options 第二部分主要记录Options 模型 OptionsConfigurationServiceCo ...
- 一个由正则表达式引发的血案 vs2017使用rdlc实现批量打印 vs2017使用rdlc [asp.net core 源码分析] 01 - Session SignalR sql for xml path用法 MemCahe C# 操作Excel图形——绘制、读取、隐藏、删除图形 IOC,DIP,DI,IoC容器
1. 血案由来 近期我在为Lazada卖家中心做一个自助注册的项目,其中的shop name校验规则较为复杂,要求:1. 英文字母大小写2. 数字3. 越南文4. 一些特殊字符,如“&”,“- ...
随机推荐
- Sublime Text 3结合Chrome实现网页的自动刷新
我们在编写前端代码时,写好一部分代码时想要看一看代码的实现效果,每次都要手动刷新会非常麻烦,神器来了,LiveReload插件实现网页的实时刷新,操作方法如下: 1. 官网下载Sublime Text ...
- C++基础之参数重载
目录 缺省参数 注意事项 缺省参数 缺省参数是在函数定义时或者声明时给参数一个默认值,当调用参数时没有给函数参数,使用默认的函数参数. 先简单的写几行代码认识一下缺省参数 以上三段代码分别位于三个文件 ...
- 如何在Eclipse中搭建MyBatis基本开发环境?(使用Eclipse创建Maven项目)
实现要求: 在Eclipse中搭建MyBatis基本开发环境. 实现步骤: 1.使用Eclipse创建Maven项目.File >> New >> Maven Project ...
- 编写Java程序,使用单例模式,创建可以生成银联借记卡号的工具类,银联借记卡号是一个 19 位的数字,卡号以“62”开头,如图所示。
查看本章节 查看作业目录 需求说明: 使用单例模式,创建可以生成银联借记卡号的工具类,银联借记卡号是一个 19 位的数字,卡号以"62"开头,如图所示. 实现思路: (1)创建 J ...
- 使用 windows bat 脚本命令一键实现快速配置JDK 环境变量
%1 mshta vbscript:CreateObject("Shell.Application").ShellExecute("cmd.exe"," ...
- Python学习笔记:利用pd.get_dummies实现哑变量编码
一.理论介绍 虚拟变量(dummy variable)也叫哑变量,是一种将多分类变量转换为二分变量的一种形式. 如果多分类变量有k个类别,则可以转化为k-1个二分变量. 需要有一个参照的类别. 在非线 ...
- 在CentOS7系统安装与配置RabbitMQ
在CentOS7系统安装与配置RabbitMQ 远程访问需要开放端口 https://www.cnblogs.com/heqiuyong/p/10460150.html
- centos6.5-搭建LNMP
安装LNMP 一.安装nginx 1.安装相关组件 yum -y install pcre-devel zlib-devel 2.创建启动用户 useradd -M -s /sbin/nologin ...
- Linux_无法解析域名
现象如下:ping baidu.com不通,但是ping 114.114.114.114能通 产生的问题:无法使用 wget下载包 解决方法:增加DNS配置. 注:配置的域名解析地址必须能Ping通.
- 自带排序 Array.sort()
public static void main(String[] args) { int[] aa = {1, 5, 9, 7, 3, 1, 6, 3, 47}; Arrays.sort(aa); p ...