Microsoft.Extensions 简介

Microsoft.Extensions 简介

一、Microsoft.Extensions 简介

.NET Extensions 是一套官方的、开源的、跨平台的 API 集合,提供了一些常用的编程模式和实用工具,例如依赖项注入、日志记录、缓存、Host以及配置等等。该项目的大多数 API 都被用在 .NET 平台的各个应用框架上,如 http://ASP.NET Core,Xamarin 等等。虽然 http://ASP.NET 使用了很多这些 API 但 http://ASP.NET 并没有与它们紧密耦合。你也可以在控制台应用程序、WinForm以及WPF应用程序上使用它们。总结一句就是:它是官方造的“轮子”

**

NET API browser 中的 .NET Platform Extensions
.NET Platform Extensions 包括下面所列的包,由于 .NET 5 正在整合各个代码仓库,所以 .NET Extension 中的部分代码仓库已经分别以迁移到了 dotnet/runtime 和 dotnet/aspnetcore 这两个仓库中。## 移动到 dotnet/runtime 的包:## **Caching**Microsoft.Extensions.Caching.Abstractions
Microsoft.Extensions.Caching.Memory## ConfigurationMicrosoft.Extensions.Configuration
Microsoft.Extensions.Configuration.Abstractions
Microsoft.Extensions.Configuration.Binder
Microsoft.Extensions.Configuration.CommandLine
Microsoft.Extensions.Configuration.EnvironmentVariables
Microsoft.Extensions.Configuration.FileExtensions
Microsoft.Extensions.Configuration.Ini
Microsoft.Extensions.Configuration.Json
Microsoft.Extensions.Configuration.UserSecrets
Microsoft.Extensions.Configuration.Xml## Dependency InjectionMicrosoft.Extensions.DependencyInjection
Microsoft.Extensions.DependencyInjection.Abstractions## File ProvidersMicrosoft.Extensions.FileProviders.Abstractions
Microsoft.Extensions.FileProviders.Composite
Microsoft.Extensions.FileProviders.Physical
File System Globbing
Microsoft.Extensions.FileSystemGlobbing## HostingMicrosoft.Extensions.Hosting
Microsoft.Extensions.Hosting.Abstractions
Http Client Factory
Microsoft.Extensions.Http## LoggingMicrosoft.Extensions.Logging
Microsoft.Extensions.Logging.Abstractions
Microsoft.Extensions.Logging.Configuration
Microsoft.Extensions.Logging.Console
Microsoft.Extensions.Logging.Debug
Microsoft.Extensions.Logging.EventLog
Microsoft.Extensions.Logging.EventSource
Microsoft.Extensions.Logging.Testing
Microsoft.Extensions.Logging.TraceSource## OptionsMicrosoft.Extensions.Options
Microsoft.Extensions.Options.ConfigurationExtensions
Microsoft.Extensions.Options.DataAnnotations## PrimitivesMicrosoft.Extensions.Primitives## 移动到 dotnet/aspnetcore 的包:## ConfigurationMicrosoft.Extensions.Configuration.KeyPerFile## File ProvidersMicrosoft.Extensions.FileProviders.Embedded
Microsoft.Extensions.FileProviders.Embedded.Manifest.Task## Health ChecksMicrosoft.Extensions.Diagnostics.HealthChecks
Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions## JS InteropMicrosoft.JSInterop
Mono.WebAssembly.Interop## LocalizationMicrosoft.Extensions.Localization
Microsoft.Extensions.Localization.Abstractions## LoggingMicrosoft.Extensions.Logging.AzureAppServices## Object PoolMicrosoft.Extensions.ObjectPool
Web Encoders
Microsoft.Extensions.WebEncoders## 目前仍在 dotnet/extensions 的包:## CachingMicrosoft.Extensions.Caching.SqlServer
Microsoft.Extensions.Caching.StackExchangeRedis## ConfigurationMicrosoft.Extensions.Configuration.NewtonsoftJson## HostingMicrosoft.Extensions.Hosting.Systemd
Microsoft.Extensions.Hosting.WindowsServices## Http Client FactoryMicrosoft.Extensions.Http.Polly## LoggingMicrosoft.Extensions.Logging.Analyzers (has not been released to NuGet.org as of writing)
Microsoft.Extensions.DependencyInjection.Specification.Tests

二、什么是依赖注入?

**
依赖注入,字面理解就是将依赖注入到你的代码中,那么为什么需要将依赖注入到你的代码中呢?以及怎么注入到你的代码?下面我们来一步一步来了解整个过程。
1)首先,通常情况下当我们要使用另外一个类型时我们会使用下面的代码来生成一个该类型的实例。

var a = new ClassA();
a.MehtodA();

此时相当于我们的代码依赖了ClassA,一旦 ClassA 发生了改变我们的代码也就需要发生相应的改变,这不符合松耦合的设计原则,那么我们应该怎么做呢?

2)为了让我们的代码不直接依赖于 ClassA 我们来定义一个接口 InterfaceA,

interface InterfaceA
{void MethodA();
}

并让== ClassA 实现该接口==,那么我们就可以这样写我们的代码了,

InterfaceA a = new ClassA();
a.MethodA();

此时我们的代码本质上是对 InterfaceA 的依赖,并不关心 InterfaceA 的具体实现。不过目前好像没什么鸟用,因为我们的代码中仍然需要显式实例化 ClassA这时候我们就希望能有一个神奇的工具能给我们一个 InterfaceA 的实例了。

3)现在 IoC 容器就闪亮登场了(IoC, Inversion of Control / 控制反转),它可以使用多种方式给我们的代码中注入我所需要的 InterfaceA 实例,下面的代码就是利用构造函数注入依赖。

public class MyCode
{private InterfaceA _ia;public MyCode(InterfaceA ia){_ia = ia;}public void MyMethod(){_ia.MethodA();}
}

这样在我们的代码里就看不到 ClassA 了,我们的代码也就脱离了对 ClassA的依赖,实现了松耦合,也践行了部分面向对象的设计原则,如依赖倒置(DIP)原则。

下面我们使用 Microsoft.Extensions 中的 DependencyInjection 容器(在下文中我们简称为DI容器)来实现上面示例的完整代码。

using System;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;namespace DemoCode
{class Program{static void Main(string[] args){//初始化容器IServiceCollection ioc = new ServiceCollection();//这里的是添加服务到容器中//Transient指的是服务实例的生命周期,即每次请求服务的时候都会创建一个新的实例ioc.TryAddTransient<MyCode>();ioc.TryAddTransient<InterfaceA, ClassA>();//创建serviceProvider对象来获取服务的实例var serviceProvider = ioc.BuildServiceProvider();var myCodeinstance = serviceProvider.GetService<MyCode>();//调用我们定义的方法myCodeinstance .Run();}}//public class MyCode{private InterfaceA _ia;public MyCode(InterfaceA ia){_ia = ia;}public void Run(){_ia.MethodA();}}//定义服务的接口public interface InterfaceA{void MethodA();}//服务的具体实现public class ClassA : InterfaceA{public void MethodA(){Console.WriteLine("MethodA 被调用");}}
}

依赖注入以及控制反转都属于设计模式(Design Pattern),并且通常情况下,要实现控制反转就需要基于依赖注入。它们都是为了遵从面向对象语言的设计原则 S.O.L.I.D 而产生的。

S: Single responsibility / 单一职责
O: Open closed / 开闭原则(对扩展开放,对修改关闭)
L: Liskov substitution / 里氏替换
I: Interface segregation / 接口分离
D: Dependency inversion / 依赖倒置
关于S.O.L.I.D 的更多内容可以查看下面这篇文章,

S.O.L.I.D: The First 5 Principles of Object Oriented Design​scotch.io
在这里插入图片描述

三、DI容器的使用方法

1、引用

Microsoft.Extensions.DependencyInjection.Abstractions
Microsoft.Extensions.DependencyInjection
这两个包含了容器的抽象以及容器的具体实现,其中Microsoft.Extensions.DependencyInjection.Abstractions 为抽象,Microsoft.Extensions.DependencyInjection 则为具体实现。

当你要在自己的程序中使用时,使用nuget包管理工具安装 Microsoft.Extensions.DependencyInjection 包即可。
2、主要类型

1、引用类型
使用 DI 容器需要熟悉下面的接口与类型,Microsoft.Extensions.DependencyInjection.IServiceCollection,该接口包含了一系列 Add 扩展方法来添加你的服务,该接口的默认实现为 Microsoft.Extensions.DependencyInjection.ServiceCollection 类。

容器接口叫做 IServiceCollection 是因为 “微软”将容器中的类型视为我们程序所需的服务,有了这个前提将它命名为 “ServiceCollection”也就非常合理了。

System.IServiceProvider,使用 IServiceCollection 的扩展方法 BuildServiceProvider() 可以得到一个默认的 ServiceProvider 对象来让我们获取服务实例,ServiceProvider 实现了IServiceProvider 接口,该接口包含了一个 GetService() 方法来获取服务。IServiceProvider 接口的默认实现为 Microsoft.Extensions.DependencyInjection.ServiceProvider 类。
2、IServiceCollection,添加服务与生命周期

IServiceCollection 接口包含一系列的扩张方法让我们方便的添加服务,常用的包括下面三个方法,

  1. AddTransient,添加生命周期为Transient(短暂)的服务,这样的服务在每次被请求是都会创建一个新的实例
  2. AddSingleton
    ,添加生命周期为Singleton(单例)的服务,这样的服务只有在首次请求是创建一个新的实例,之后都会使用这个实例
  3. AddScoped,添加生命周期为Scoped(域内)的服务,这样的服务在一个自定义的“作用域”范围内是单例的。例如,在
    http://ASP.NET Core 中 Scoped 服务在每一次请求中都是一个实例。 除此之外你也可以使用 Add 方法,并使用
    ServiceLifetime 在参数中指定生命周期。

除了上面这三个常用方法之外,还有 TryAddTransient、TryAddSingleton、TryAddScoped 这三个用于添加服务的方法,与之前所提三个方法的区别在于带 Try 的这三个方法在添加服务时会检查服务是否已存在,若已经存在则不再添加。
3、IServiceProvider,获取服务与注入依赖
你可以使用 IServiceCollection 的 BuildServiceProvider() 方法来获取 IServiceProvider 对象,使用 GetServices 方法便可以获取你添加到容器中的服务,对于 Transient 和 Singleton 的服务使用这个方法便可以实现其对应的生命周期逻辑。

Scoped的情况相对有点复杂,如果你直接使用 IServiceProvider 的 GetServices()方法获取服务那么Scoped 服务的行为就和 Singleton 是一样的,它的的生命周期和 IServiceProvider 对象是一致的,下面的代码演示了如何使用 ScopedService,


//在using的作用域内scopeService是单例的
//在创建新的Scope之后,容器会创建新的scopedService实例
using (var scope = serviceProvider.CreateScope())
{var scopedServiceProvider = scope.ServiceProvider;var myScopedService = scopedServiceProvider.GetService<IMyScopedService>();
}

除了使用容器直接获取服务,我们还需要了解容器的注入方式,ioc容器的注入通常有三种方法

  1. 构造函数注入,在构造函数中将服务已参数的方式注入到类中。
  2. 方法注入,通过指定的方法将服务实例传入类中。
  3. 属性注入,通过设置实例到属性将服务实例注入到类中。DI 容器暂不支持该注入方式。

构造函数注入在上面已经演示了,下面是 http://ASP.NET Core 自定义Middleware 中方法注入的示例代码,

public class CustomMiddleware
{private readonly RequestDelegate _next;public CustomMiddleware(RequestDelegate next){_next = next;}//在Invoke方法中,将IMyScopedService服务注入到类中。public async Task Invoke(HttpContext httpContext, IMyScopedService svc){svc.MyProperty = 1000;await _next(httpContext);}

四、在 http://ASP.NET Core 中替换容器实现

DI 容器相对于其他第三方更加成熟的 IoC 容器来说,功能并不是十分完善,下面是 DI 容器暂时不支持的功能。

  • 属性注入
  • 基于名称的注入
  • 子容器
  • 自定义的生命周期管理
  • 支持 Func 的延迟初始化
  • 基于约定的注册

不过在 DI 容器能满足你需求的情况下,微软还是建议使用该容器。 如果它不能满足你的需求,你可以选择下面推荐的第三方 IoC 容器。

  • Autofac
  • DryIoc
  • Grace
  • LightInject
  • Lamar
  • Stashbox
  • Unity

不过在 http://ASP.NET Core 中情况比较特殊,由于 http://ASP.NET Core 是基于 DI 容器的,所以要在http://ASP.NET Core 中使用其他容器,就需要替换 IServiceProvider 的实现。下面的代码展示的是如何在 http://ASP.NET Core 中集成 Autofac 容器。


public class Program
{public static void Main(string[] args){// 适用于ASP.NET Core 3.0+:var host = Host.CreateDefaultBuilder(args).UseServiceProviderFactory(new AutofacServiceProviderFactory()).ConfigureWebHostDefaults(webHostBuilder => {webHostBuilder.UseContentRoot(Directory.GetCurrentDirectory()).UseIISIntegration().UseStartup<Startup>();}).Build();host.Run();}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/120914.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Jetpack:019-Jetpack的导航二(传递数据)

文章目录 1. 知识回顾2. 使用方法2.1 通过参数传递数据2.2 获取参数中的数据2.3 共享导航控制器 3. 示例代码4. 内容总结 我们在上一章回中介绍了Jetpack中导航相关的内容&#xff0c;本章回中 继续介绍导航相关的内容。闲话休提&#xff0c;让我们一起Talk Android Jetpack吧…

reactNative导入excel文件

组件内导入 import {TouchableOpacity,PermissionsAndroid} from react-native; import RNFS from react-native-fs; import XLSX from xlsx; import DocumentPicker from react-native-document-picker; import {Buffer} from buffer;// 需要安装一下三个,Buffer和react-nati…

Node编写更新用户头像接口

目录 定义路由和处理函数 验证表单数据 ​编辑 实现更新用户头像的功能 定义路由和处理函数 向外共享定义的更新用户头像处理函数 // 更新用户头像的处理函数 exports.updateAvatar (req, res) > {res.send(更新成功) } 定义更新用户头像路由 // 更新用户头像的路由…

安装 tensorflow==1.15.2 遇见的问题

一、直接安装 命令&#xff1a;pip install tensorflow1.15.2 二、换 阿里云 镜像源 命令&#xff1a;pip install -i http://mirrors.aliyun.com/pypi/simple tensorflow1.15.2 三、换 豆瓣 镜像源 命令&#xff1a;pip install http://pypi.douban.com/simple tensorflow1…

【OpenCV实现平滑图像形态学变化】

文章目录 概要目标腐蚀膨胀开运算结构元素&#xff08;内核&#xff09;小结 概要 形态学变化是一组简单的图像操作&#xff0c;主要用于处理二值图像&#xff0c;即只包含黑和白两种颜色的图像。这些操作通常需要两个输入&#xff0c;原始图像和一个内核&#xff08;kernel&a…

第13期 | GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区&#xff0c;集成了生成预训练 Transformer&#xff08;GPT&#xff09;、人工智能生成内容&#xff08;AIGC&#xff09;以及大型语言模型&#xff08;LLM&#xff09;等安全领域应用的知识。在这里&#xff0c;您可以…

接口自动化测试实战

实现思路 使用excel管理用例用例信息&#xff0c;requests模块发送http请求&#xff0c;实现了记录日志&#xff0c;邮件发送测试报告的功能 目录结构如下&#xff1a; 同时&#xff0c;我也准备了一份软件测试视频教程&#xff08;含接口、自动化、性能等&#xff09;&#…

MySQL 连接出现 Authentication plugin ‘caching_sha2_password的处理方法(使用第二种)

出现这个原因是mysql8 之前的版本中加密规则是mysql_native_password,而在mysql8之后,加密规则是caching_sha2_password, 解决问题方法有两种,一种是升级navicat驱动,一种是把mysql用户登录密码加密规则还原成mysql_native_password. 1. 升级MySQL版本 较早的MySQL版本可能不…

TSINGSEE青犀老旧小区升级改造AI+视频监控方案

一、背景与需求 近年来&#xff0c;政府高度重视城镇老旧小区改造工作&#xff0c;强调要加快老旧小区改造&#xff0c;不断完善城市管理和服务&#xff0c;彻底改变粗放型管理方式&#xff0c;让人民群众在城市生活得更方便、更舒心、更美好。老旧小区升级改造面临以下问题&a…

Kotlin中使用ViewBinding绑定控件并添加点击事件

文章目录 效果1、加入依赖2、与控件进行绑定在 Activity 中使用视图绑定 3、监听控件 效果 实现源码 class MainActivity : AppCompatActivity() {lateinit var binding:ActivityMainBindingoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstan…

计算机毕业设计 基于SpringBoot大学生创新创业项目管理系统的设计与实现 Javaweb项目 Java实战项目 前后端分离 文档报告 代码讲解 安装调试

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

【安装tensorflow-CPU版本】

一、安装目的二、安装过程三、总结 一、安装目的 使自己的jupyter能用tensorflow 二、安装过程 首先打开anaconda prompt 接着输入conda list 查看自己是否安装了tensorflow 在 Python 中使用 pip 工具来升级 pip 自身并指定了使用清华大学的镜像源进行安装 python -m pip …

DoLa:对比层解码提高大型语言模型的事实性

DoLa&#xff1a;对比层解码提高大型语言模型的事实性 摘要1 引言2 方法2.1 事实知识在不同层级上演化2.2 动态早期层选择2.3 预测对比 3 实验3.1 任务3.2 实验设置3.3 多项选择3.3.1 TruthfulQA&#xff1a;多项选择3.3.2 FACTOR&#xff1a;维基、新闻 3.4 开放式文本生成3.4…

开始学习Go编程

探索Go编程中的语法、数据类型和控制流 Go&#xff0c;又称为Golang&#xff0c;因其简单性、性能和效率而广受欢迎。在本文中&#xff0c;我们将深入研究构成Go编程语言基础的基本概念。从理解其语法和数据类型到掌握控制流和函数&#xff0c;我们将为您提供启动Go编程之旅所…

利用JMeter生成加密数据写入数据库

有部分数据直接插入数据库是不可以的&#xff0c;需要加密处理&#xff0c;例如密码都指定为加密后的数据字符串。今天我们来学习一下如何利用JMeter生成加密数据并写入MySQL数据库中。如何JMeter如何连接数据库&#xff0c;可以看我之前写的随笔&#xff0c;JMeter接口测试-JD…

Linux之线程池

线程池 线程池概念线程池的应用场景线程池实现原理单例模式下线程池实现STL、智能指针和线程安全其他常见的各种锁 线程池概念 线程池&#xff1a;一种线程使用模式。 线程过多会带来调度开销&#xff0c;进而影响缓存局部性和整体性能。而线程池维护着多个线程&#xff0c;等待…

基于机器视觉的手势检测和识别算法 计算机竞赛

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于深度学习的手势检测与识别算法 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f9ff; 更多资料, 项目分享&#xff1a; https://gitee.com/dancheng…

【代码随想录】算法训练计划03

1、203. 移除链表元素 题目&#xff1a; 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 输入&#xff1a;head [1,2,6,3,4,5,6], val 6 输出&#xff1a;[1,2,3,4,5] 思路&#xf…

linux进程间通信

文章目录 前言一、管道通信1、进程间通信目的2、进程间通信分类3、匿名管道通信3.1 匿名管道通信介绍3.2 匿名管道通信3.3 匿名管道读写规则3.4 匿名管道特点3.5 站在文件描述符角度-深度理解管道3.6 站在内核角度-管道本质 4、进程池练习5、命名管道6、匿名管道与命名管道的区…

智慧公厕:细致入微的城市贴心服务与便捷方便的生活配套

在现代城市生活中&#xff0c;公厕作为重要的城市基础设施&#xff0c;一直是城市发展的关键环节之一。然而&#xff0c;传统的公厕常常存在着设施陈旧、管理不善和卫生状况差等问题&#xff0c;给市民的生活品质和城市形象带来了一定的影响。为了提供更好的城市公厕服务&#…