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

## Configuration

Microsoft.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 Injection

Microsoft.Extensions.DependencyInjection
Microsoft.Extensions.DependencyInjection.Abstractions

## File Providers

Microsoft.Extensions.FileProviders.Abstractions
Microsoft.Extensions.FileProviders.Composite
Microsoft.Extensions.FileProviders.Physical
File System Globbing
Microsoft.Extensions.FileSystemGlobbing

## Hosting

Microsoft.Extensions.Hosting
Microsoft.Extensions.Hosting.Abstractions
Http Client Factory
Microsoft.Extensions.Http

## Logging

Microsoft.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

## Options

Microsoft.Extensions.Options
Microsoft.Extensions.Options.ConfigurationExtensions
Microsoft.Extensions.Options.DataAnnotations

## Primitives

Microsoft.Extensions.Primitives

## 移动到 dotnet/aspnetcore 的包:

## Configuration

Microsoft.Extensions.Configuration.KeyPerFile

## File Providers

Microsoft.Extensions.FileProviders.Embedded
Microsoft.Extensions.FileProviders.Embedded.Manifest.Task

## Health Checks

Microsoft.Extensions.Diagnostics.HealthChecks
Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions

## JS Interop

Microsoft.JSInterop
Mono.WebAssembly.Interop

## Localization

Microsoft.Extensions.Localization
Microsoft.Extensions.Localization.Abstractions

## Logging

Microsoft.Extensions.Logging.AzureAppServices

## Object Pool

Microsoft.Extensions.ObjectPool
Web Encoders
Microsoft.Extensions.WebEncoders

## 目前仍在 dotnet/extensions 的包:

## Caching

Microsoft.Extensions.Caching.SqlServer
Microsoft.Extensions.Caching.StackExchangeRedis

## Configuration

Microsoft.Extensions.Configuration.NewtonsoftJson

## Hosting

Microsoft.Extensions.Hosting.Systemd
Microsoft.Extensions.Hosting.WindowsServices

## Http Client Factory

Microsoft.Extensions.Http.Polly

## Logging

Microsoft.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();
  }
 }



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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

java毕业设计基于springboot的民宿预订信息网站

运行环境 开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven 项目介绍 民宿短租…

SDRAM学习笔记(MT48LC16M16A2,w9812g6kh)

一、基本知识 SDRAM : 即同步动态随机存储器&#xff08;Synchronous Dynamic Random Access Memory&#xff09;, 同步是指其时钟频率与对应控制器&#xff08;CPU/FPGA&#xff09;的系统时钟频率相同&#xff0c;并且内部命令 的发送与数据传输都是以该时钟为基准&#xff…

canvas基础3 -- 交互

点击交互 使用 isPointInPath(x, y) 判断鼠标点击位置在不在图形内 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"&…

mac电脑怎么永久性彻底删除文件?

Mac老用户都知道在我们查看Mac内存时都会发现有一条“其他文件”占比非常高&#xff0c;它是Mac储存空间中的“其他”数据包含不可移除的移动资源&#xff0c;如&#xff0c;Siri 语音、字体、词典、钥匙串和 CloudKit 数据库、系统无法删除缓存的文件等。这些“其他文件”无用…

腾讯云优惠券、代金券、云服务器折扣券领取方法及使用教程

腾讯云优惠券是腾讯云为用户提供的一种优惠活动&#xff0c;通常包括代金券和折扣券两种类型&#xff0c;代金券可以在购买腾讯云相关产品时直接抵扣订单金额&#xff0c;而折扣券则可以在购买腾讯云相关产品时享受一定的折扣。 腾讯云作为国内领先的云计算服务提供商&#xff…

时间、空间复杂度的例题详解

文章前言 上篇文章带大家认识了数据结构和算法的含义&#xff0c;以及理解了时间、空间复杂度&#xff0c;那么接下来来深入理解一下时间、空间复杂度。 时间复杂度实例 实例1 // 计算Func2的时间复杂度&#xff1f; void Func2(int N) {int count 0;for (int k 0; k <…

eslint提示 xxx should be listed in the project's dependencies

有时候手动安装了一个npm包A&#xff0c;npm包A里面包含了npm包B&#xff0c;这时候如果 import xxx from npm包B;eslint会报错&#xff0c;提示 npm包B 不在 package.json 里面 解决方法&#xff1a;在 eslintrc.js 增加配置 module.exports {rules: {import/no-extraneous-d…

docker和K8S环境xxl-job定时任务不执行问题总结

文章目录 xxl-job 任务调度原理1 问题1 时区导致的任务没有执行的问题解决方案 2 执行器注册和下线导致的问题&#xff08;IP问题&#xff09;解决方案 3 问题3 调度成功&#xff0c;但是执行器的定时任务未执行4 问题4 数据库性能问题&#xff0c;导致查询任务和操作日志数据卡…

Ocelot简易教程目录

Ocelot简易教程目录 这里写目录标题 Ocelot简易教程目录 Ocelot简易教程&#xff08;一&#xff09;之Ocelot是什么Ocelot简易教程&#xff08;二&#xff09;之快速开始1Ocelot简易教程&#xff08;二&#xff09;之快速开始2Ocelot简易教程&#xff08;三&#xff09;之主要特…

Linux MMC子系统 - 2.eMMC 5.1总线协议浅析

By: Ailson Jack Date: 2023.10.27 个人博客&#xff1a;http://www.only2fire.com/ 本文在我博客的地址是&#xff1a;http://www.only2fire.com/archives/161.html&#xff0c;排版更好&#xff0c;便于学习&#xff0c;也可以去我博客逛逛&#xff0c;兴许有你想要的内容呢。…

Qt界面实现中英文切换

要实现的效果&#xff0c;是下拉列表切换中文和English实现按钮文本中英文内容切换。 实现步骤&#xff1a; 1.在VS中鼠标对Translation Files文件右击&#xff0c;选择“添加”--->“模块”. 在弹窗的窗口中选择“Qt”--->“Qt Translation File”。 添加Translation_e…

50个常用的Java代码示例

50个常用的Java代码示例 1.输出语句&#xff1a; System.out.println(Hello World!);2.定义变量&#xff1a; int x 5; String name John;3.循环语句&#xff1a; for(int i 0; i < 10; i) {System.out.println(i);}4.条件语句&#xff1a; if(x > 0) {System.ou…

MQTT(详解)

什么是MQTT MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;是一种轻量级的通信协议&#xff0c;用于在设备之间传输消息。它通常用于物联网&#xff08;IoT&#xff09;和传感器网络中&#xff0c;可以在不同设备之间进行可靠的通信&#xff0c;而且资源消耗…

YOLOv5配置文件之 - yaml

在YOLOv5的目录中&#xff0c;models文件夹里存储了YOLO的模型配置。 ./models/yolov5.yaml 定义了YOLOv5s网络结构的定义文件 yaml的主要内容 参数配置 nc: 80 类别数量 depth_multiple: 0.33 模型深度缩放因子 width_multiple: 0.50 控制卷积特征图的通道个数 anchors配…

【Docker】Docker-Compose内置DNS负载均衡失效问题

Docker Compose实现负载均衡 还是对前面的例子docker-compose.yml稍微修改&#xff1a; version: "3.8"services:flask-demo:build:context: .dockerfile: Dockerfileimage: flask-demo:latestenvironment:- REDIS_HOSTredis-server- REDIS_PASS${REDIS_PASS}healt…

N-129基于springboot,vue学生宿舍管理系统

开发工具&#xff1a;IDEA 服务器&#xff1a;Tomcat9.0&#xff0c; jdk1.8 项目构建&#xff1a;maven 数据库&#xff1a;mysql5.7 系统分前后台&#xff0c;项目采用前后端分离 前端技术&#xff1a;vuevue-element-admin 服务端技术&#xff1a;springboot,mybatis…

UML中类之间的六种主要关系

UML中类之间的六种主要关系: 继承&#xff08;泛化&#xff09;&#xff08;Inheritance、Generalization&#xff09;, 实现&#xff08;Realization&#xff09;&#xff0c;关联&#xff08;Association)&#xff0c;聚合&#xff08;Aggregation&#xff09;&#xff0c;组…

JDK API Diff Report Generator-Java版本对比工具

今天查资料找到了除了EMT4J之外&#xff0c;其他可以用于Java版本迁移的工具。 这里简单的记录一下。 非Java er&#xff0c;有不同意见欢迎评论区交流。 JDK API Diff Report Generator JDK API Diff是一个用于比较不同Java版本API区别的工具。github地址在这里。 例如&am…

Android---StartActivity启动过程

在手机桌面应用中点击某一个 icon 之后&#xff0c;最终是通过 startActivity 去打开某一个 Activity 页面。我们知道&#xff0c;Android 中的一个 APP 就相当于一个进程。所以&#xff0c;startActivity 操作中还需要判断&#xff0c;目标 Activity 的进程是否已经创建。如果…

竞赛选题 深度学习人体跌倒检测 -yolo 机器视觉 opencv python

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **基于深度学习的人体跌倒检测算法研究与实现 ** 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f947;学长这里给一个题目综合评分(每项满…