重新整理.net core 计1400篇[九] (.net core 中的依赖注入的服务注入)
前言
在该系列六中介绍了一个简单的依赖注入,该节介绍.net core 中的依赖注入的服务注入。
ServiceDescriptor
ServiceDescriptor 是服务描述的意思,这个是做什么的呢?
我们知道当我们要实例化一个服务的时候,我们通过serviceType 属性去查找,是否我们注册了。
那么通过serviceType 查找到的是什么呢?就是这个ServiceDescriptor,好了那么分析一下这个serviceDescriptor 到底是什么吧。
来看一下又什么属性吧!
public ServiceLifetime Lifetime
{
[CompilerGenerated]
get;
}
/// <inheritdoc />
public Type ServiceType
{
[CompilerGenerated]
get;
}
/// <inheritdoc />
public Type ImplementationType
{
[CompilerGenerated]
get;
}
/// <inheritdoc />
public object ImplementationInstance
{
[CompilerGenerated]
get;
}
/// <inheritdoc />
public Func<IServiceProvider, object> ImplementationFactory
{
[CompilerGenerated]
get;
}
下面来介绍一下属性。
Lifetime 这个我想不用介绍了吧,生命周期。
public enum ServiceLifetime
{
/// <summary>
/// Specifies that a single instance of the service will be created.
/// </summary>
Singleton,
/// <summary>
/// Specifies that a new instance of the service will be created for each scope.
/// </summary>
/// <remarks>
/// In ASP.NET Core applications a scope is created around each server request.
/// </remarks>
Scoped,
/// <summary>
/// Specifies that a new instance of the service will be created every time it is requested.
/// </summary>
Transient
}
ServiceType,我想我也不用介绍的,就是当前注入类型,比如说IFoo
然后呢,下面三种属性体现了,提供服务实例的三种方式:
/// <inheritdoc />
public Type ImplementationType
{
[CompilerGenerated]
get;
}
/// <inheritdoc />
public object ImplementationInstance
{
[CompilerGenerated]
get;
}
/// <inheritdoc />
public Func<IServiceProvider, object> ImplementationFactory
{
[CompilerGenerated]
get;
}
这个需要我们来看下这个的时候ServiceDescriptor的构造函数。
/// <summary>
/// Initializes a new instance of <see cref="T:Microsoft.Extensions.DependencyInjection.ServiceDescriptor" /> with the specified <paramref name="implementationType" />.
/// </summary>
/// <param name="serviceType">The <see cref="T:System.Type" /> of the service.</param>
/// <param name="implementationType">The <see cref="T:System.Type" /> implementing the service.</param>
/// <param name="lifetime">The <see cref="T:Microsoft.Extensions.DependencyInjection.ServiceLifetime" /> of the service.</param>
public ServiceDescriptor(Type serviceType, Type implementationType, ServiceLifetime lifetime)
: this(serviceType, lifetime)
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
if (serviceType == (Type)null)
{
throw new ArgumentNullException("serviceType");
}
if (implementationType == (Type)null)
{
throw new ArgumentNullException("implementationType");
}
ImplementationType = implementationType;
}
/// <summary>
/// Initializes a new instance of <see cref="T:Microsoft.Extensions.DependencyInjection.ServiceDescriptor" /> with the specified <paramref name="instance" />
/// as a <see cref="F:Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton" />.
/// </summary>
/// <param name="serviceType">The <see cref="T:System.Type" /> of the service.</param>
/// <param name="instance">The instance implementing the service.</param>
public ServiceDescriptor(Type serviceType, object instance)
: this(serviceType, ServiceLifetime.Singleton)
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
if (serviceType == (Type)null)
{
throw new ArgumentNullException("serviceType");
}
if (instance == null)
{
throw new ArgumentNullException("instance");
}
ImplementationInstance = instance;
}
/// <summary>
/// Initializes a new instance of <see cref="T:Microsoft.Extensions.DependencyInjection.ServiceDescriptor" /> with the specified <paramref name="factory" />.
/// </summary>
/// <param name="serviceType">The <see cref="T:System.Type" /> of the service.</param>
/// <param name="factory">A factory used for creating service instances.</param>
/// <param name="lifetime">The <see cref="T:Microsoft.Extensions.DependencyInjection.ServiceLifetime" /> of the service.</param>
public ServiceDescriptor(Type serviceType, Func<IServiceProvider, object> factory, ServiceLifetime lifetime)
: this(serviceType, lifetime)
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
if (serviceType == (Type)null)
{
throw new ArgumentNullException("serviceType");
}
if (factory == null)
{
throw new ArgumentNullException("factory");
}
ImplementationFactory = factory;
}
我们看到了这三个构造方法,那么我们基本明白了,到时候创建服务实例的时候就是这几种方法了。
这里面有一个值得注意的地方,就是:
public ServiceDescriptor(Type serviceType, object instance)
: this(serviceType, ServiceLifetime.Singleton)
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
if (serviceType == (Type)null)
{
throw new ArgumentNullException("serviceType");
}
if (instance == null)
{
throw new ArgumentNullException("instance");
}
ImplementationInstance = instance;
}
也就是说我们可以直接让接口对应实例,比如说:new ServiceDescriptor(IFoo,new Foo());默认的生命周期模式就是:ServiceLifetime.Singleton
IServiceCollection
依赖存储框架将服务注册存储在一个通过IServiceCollection 接口表示的集合中。
public interface IServiceCollection : IList<ServiceDescriptor>, ICollection<ServiceDescriptor>, IEnumerable<ServiceDescriptor>, IEnumerable```
{
}
在 IServiceCollection 中,本质上其实就是一个ServiceDescriptor集合。
那么来看下IServiceCollection的实例对象ServiceCollection的扩展方法ServiceCollectionServiceExtensions。
private static IServiceCollection Add(IServiceCollection collection, Type serviceType, Type implementationType, ServiceLifetime lifetime)
{
ServiceDescriptor serviceDescriptor = new ServiceDescriptor(serviceType, implementationType, lifetime);
((ICollection<ServiceDescriptor>)collection).Add(serviceDescriptor);
return collection;
}
private static IServiceCollection Add(IServiceCollection collection, Type serviceType, Func<IServiceProvider, object> implementationFactory, ServiceLifetime lifetime)
{
ServiceDescriptor serviceDescriptor = new ServiceDescriptor(serviceType, implementationFactory, lifetime);
((ICollection<ServiceDescriptor>)collection).Add(serviceDescriptor);
return collection;
}
可以帮助我们直接创建ServiceDescriptor,并且加入到当前的ServiceCollection 中。
然后ServiceCollectionServiceExtensions 在3.0在还更新了,tryadd,因为我们一个ServiceType 可以对应多个,使用tryadd 的时候,就会尝试加入,如果有的话就不会加入。
在ServiceCollection和ServiceCollectionServiceExtensions 有一些其他的方法,最好去看一下源码,了解一下。
总结
下一章依赖注入的服务消费
重新整理.net core 计1400篇[九] (.net core 中的依赖注入的服务注入)的更多相关文章
- ASP.NET CORE MVC 2.0 如何在Filter中使用依赖注入来读取AppSettings,及.NET Core控制台项目中读取AppSettings
问: ASP.NET CORE MVC 如何在Filter中使用依赖注入来读取AppSettings 答: Dependency injection is possible in filters as ...
- ASP.NET Core 依赖注入(构造函数注入,属性注入等)
原文:ASP.NET Core 依赖注入(构造函数注入,属性注入等) 如果你不熟悉ASP.NET Core依赖注入,先阅读文章: 在ASP.NET Core中使用依赖注入 构造函数注入 构造函数注 ...
- ASP.NET Core中的依赖注入【上】
此为系列文章,对MSDN ASP.NET Core 的官方文档进行系统学习与翻译.其中或许会添加本人对 ASP.NET Core 的浅显理解 ASP.NET Core支持DI软件设计模式,其是一种为了 ...
- 重新整理 .net core 周边阅读篇————AspNetCoreRateLimit[一]
前言 整理了一下.net core 一些常见的库的源码阅读,共32个库,记100余篇. 以下只是个人的源码阅读,如有错误或者思路不正确,望请指点. 正文 github 地址为: https://git ...
- 鸿蒙内核源码分析(进程通讯篇) | 九种进程间通讯方式速揽 | 百篇博客分析OpenHarmony源码 | v28.03
百篇博客系列篇.本篇为: v28.xx 鸿蒙内核源码分析(进程通讯篇) | 九种进程间通讯方式速揽 | 51.c.h .o 进程通讯相关篇为: v26.xx 鸿蒙内核源码分析(自旋锁篇) | 自旋锁当 ...
- (Hibernate进阶)Hibernate系列——总结篇(九)
这篇博文是hibernate系列的最后一篇,既然是最后一篇,我们就应该进行一下从头到尾,整体上的总结,将这个系列的内容融会贯通. 概念 Hibernate是一个对象关系映射框架,当然从分层的角度看,我 ...
- 使用Visual Studio Code开发.NET Core看这篇就够了
作者:依乐祝 原文地址:https://www.cnblogs.com/yilezhu/p/9926078.html 在本文中,我将带着大家一步一步的通过图文的形式来演示如何在Visual Studi ...
- .NET Core实战项目之CMS 第二章 入门篇-快速入门ASP.NET Core看这篇就够了
作者:依乐祝 原文链接:https://www.cnblogs.com/yilezhu/p/9985451.html 本来这篇只是想简单介绍下ASP.NET Core MVC项目的(毕竟要照顾到很多新 ...
- .NET Core实战项目之CMS 第三章 入门篇-源码解析配置文件及依赖注入
作者:依乐祝 原文链接:https://www.cnblogs.com/yilezhu/p/9998021.html 写在前面 上篇文章我给大家讲解了ASP.NET Core的概念及为什么使用它,接着 ...
- ASP.NET Core 2.2 十九. 你扔过来个json,我怎么接
原文:ASP.NET Core 2.2 十九. 你扔过来个json,我怎么接 前文说道了Action的激活,这里有个关键的操作就是Action参数的映射与模型绑定,这里即涉及到简单的string.in ...
随机推荐
- Java 客户信息管理软件 (面向对象 封装 总结)
1 package com.bytezero.cim.bean; 2 3 /** 4 * 5 * @Description Customer为实体对象,用来封装客户信息 6 * @author Byt ...
- Java 临时笔记
1 //srand((unsignedint)time(NULL)); C 2 //获取随机数 10-99 3 4 //int value = (int)(Math.random() * 90+10) ...
- MYSQL中正则表达式检索数据库
1.MySQL中使用通配符检索数据库,之外还可以使用正则表达式来检索数据. 使用通配符 '_' 和 '%'的区别如下, 使用通配符的技巧:一般的来说 通配符可以处理数据,但是消耗内存较大 ...
- java.lang.Long cannot be cast to java.util.Map-Oracle查询异常处理
Map<String, Object> map一.问题由来 测试环境中进行测试时,某一个接口频繁报一个错,java.lang.Long cannot be cast to java.uti ...
- H3C-IP路由器
定义 路由器负责将数据报文在IP网段之间进行转发 路由器负责将数据报文在IP网段之间进行转发 路由是指导路由器如何进行数据转发的路径信息 作用 路由器负责将数据报文在逻辑网段间进行转发 路由器是指导路 ...
- chrome 快速执行 snippets 1. F12 2. Ctrl+Shift+P 3. show snippets 4. 上下选择 5. Ctrl + Enter
chrome 快速执行 snippets F12 Ctrl+Shift+P show snippets 上下选择 Ctrl + Enter
- 一种OSD 简单实现 (文字反色---opencv、字体切换---freetype2(中文、空格))
PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明 本文作为本人csdn blog的主站的备份.(Bl ...
- 记录--Uni-app接入腾讯人脸核身
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 人脸核身功能有多种接入方式,其中包含微信H5.微信小程序.APP.独立H5.PC端.API接入6种方式. 我们的产品是使用uni-ap ...
- 记录--vue3 setup 中国省市区三级联动options最简洁写法,无需任何库
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 在写页面的时候,发现表单里面有一个省市区的 options 组件要写,因为表单很多地方都会用到这个地址选择,我便以为很简单嘛. 虽然很简单 ...
- 基于proteus的4019的移位设计
基于proteus的4019的移位设计 1.实验原理 4019是一个基于CMOS的数字集成芯片,具有数据选择和逻辑门或两种工作状态.这里利用数据选择的切换,实现数据的左移和右移操作.简而言之就是左移使 ...