大家好,我是张飞洪,感谢您的阅读,我会不定期和你分享学习心得,希望我的文章能成为你成长路上的垫脚石,让我们一起精进。

在本章中,我们将学习ASP.NET Core的依赖项注入(DI)以及如何自定义它。

我们将讨论以下主题:

  • 使用不同的DI容器
  • 探索ConfigureServices方法
  • 使用其他的ServiceProvider
  • Scrutor简介

技术准备

我们使用以下命令(你可以在console, shell,Bash终端),创建一个MVC应用:

dotnet new mvc -n DiSample -o DiSample

在Visual Studio中打开项目,或在控制台中键入以下命令,在Visual Studio Code中打开项目:

cd DiSample
code .

使用不同的DI容器

在大多数项目中,我们其实不需要使用不同的DI容器。ASP.NET Core中的现有DI基本上满足我们的需要。但是,你可能喜欢在他DI容器的其他功能:

  • 使用Ninject创建一个支持模块作为轻量级依赖项的应用程序。比如,您可能希望将模块放入特定目录中,并在应用程序中自动注册这些模块。
  • 在应用程序外部的配置文件中,比如,在XML或JSON文件中,而不是仅在C#中配置服务。这是各种DI容器中的常见功能,但ASP.NET Core中尚不支持。
  • 在运行时添加服务,获取动态的DI容器,这也是一些DI容器中的常见特性。

现在,让我们看看ConfigureServices方法是如何操作的。

探索ConfigureServices方法

我们将当前的ConfigureServices方法与以前的长期支持版本(TLS)进行比较,看看有什么变化。如果您使用版本3.1创建的ASP.NET Core项目,并打开Startup.cs文件,配置服务的方法如下所示:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<CookiePolicyOptions>(options =>
    {          options.CheckConsentNeeded = context => true;
    });
    services.AddControllersWithViews();
    services.AddRazorPages();
}

相反,在 ASP.NET Core 6.0,没有启动Startup.cs,服务的配置在Startup.cs中进行,如下所示:

var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();
var app = builder.Build();
// The rest of the file isn't relevant for this chapter

这两种情况都可以获得IServiceCollection,其中默认已经填充了ASP.NET Core所需的一组服务,比如宿主服务、ConfigureServices方法之前执行的相关服务。

以上方法中,添加了更多的服务。

  • 首先,将包含cookie策略选项的配置类添加到ServiceCollection
  • AddMvc()方法添加MVC框架所需的服务。

    到目前为止,我们有大约140个服务注册到IServiceCollection

    但是,服务集合不是实际的DI容器,真实的DI容器被包装在所谓的服务提供者中(ServiceProvider)。

那么应该如何获取DI容器呢?

IServiceCollection有了一个扩展方法,它用于从服务集合中创建IServiceProvider,代码如下:

IServiceProvider provider = services.BuildServiceProvider()

ServiceProvider包含不可变容器,即在运行时无法更改。在ConfigureServices方法执行后,会在后台创建IServiceProvider

接下来,我们再看下如何在在DI定制过程中,替代IServiceProvider

使用其他IServiceProvider

如果其他容器已经支持ASP.NET Core,则更改为其他或自定义DI容器将变得非常容易。通常,第三方DI容器会使用IServiceCollection做为自己的容器,它通过循环集合将已注册的服务移动到另一个容器。

我们用Autofac作为第三方容器举个例子。在命令行中键入以下命令加载NuGet包:

dotnet add package Autofac.Extensions.DependencyInjection

要注册自定义IoC容器,通常需要注册不同的IServiceProviderFactoryIServiceProviderFactory将创建一个ServiceProvider实例。如果第三方容器支持ASP.NET Core,则必须提供一个该工厂类。如果你要使用Autofac,则需要使用AutofacServiceProviderFactory

我们在Program.cs中给IHostBuilder编写一个扩展方法,内部注册一个AutofacServiceProviderFactory

using Autofac;
using Autofac.Extensions.DependencyInjection;
namespace DiSample; public static class IHostBuilderExtension {     
public static IHostBuilder UseAutofacServiceProviderFactory(this IHostBuilder hostbuilder)    
 {         
hostbuilder.UseServiceProviderFactory (new AutofacServiceProviderFactory());         
return hostbuilder;     
}
}

注意,不要忘记将引入名称空间:AutofacAutofac.Extensions.DependencyInjection

要使用此扩展方法,可以在Program.cs中使用AutofacServiceProvider

var builder = WebApplication.CreateBuilder(args);
builder.Host.UseAutofacServiceProviderFactory();
// Add services to the container.
builder.Services.AddControllersWithViews();

以上通过扩展方法将AutofacServiceProviderFactory添加到IHostBuilder中,并启用AutofacIoC容器。后续会转而使用AutofacIServiceCollection添加服务。

再强调一下,除非必要。通常,我们不一定要替换现有的.NET CoreDI容器。

Scrutor简介

在本章的开头,我提到了服务的自动注册,这里可以通过其他DI容器完成。这里介绍一个名为Scrutor的不错的NuGet包来实现。

Scrutor通过向.NET Core DI容器向IServiceCollection添加一个扩展方法,用以自动注册服务。

扩展阅读

这里介绍一篇关于Scrutor的非常详细的博客文章,建议您继续阅读这篇文章以了解更多信息。

回顾

通过以上演示,我们将能够使用任何.NET标准兼容的DI容器替换现有容器。如果您选择的容器不包括ServiceProvider,请自己实现一个IServiceProvider接口,并在其中使用DI容器。如果您选择的容器没有提供填充服务的方法,请自行创建自己的方法。循环已注册的服务并将其添加到另一个容器中。

最后一步听起来很简单,实现起来比较费劲,因为需要将所有的IServiceCollection注册转换为其他容器的注册,它的复杂性取决于其他DI容器的实现细节。

任何时候,我们都可以选择使用任何与.NET标准兼容的DI容器,替换ASP.NET Core中的许多默认实现。

在下一章我们将探讨如何以不同的方式配置HTTPS,感谢您的阅读。

定制.NET 6.0的依赖注入的更多相关文章

  1. Asp.Net Core 3.0的依赖注入改变

    Asp.Net Core 3.0出来很久了,预览版的时候就被我偶像Lemon大人,带着尝试摸索了一下这个 那么Asp.Net Core 3.0和Asp.Net Core 2.X到底有哪些区别呢? As ...

  2. Asp.Net Mvc3.0(MEF依赖注入实例)

    前言 在http://www.cnblogs.com/aehyok/p/3386650.html前面一节主要是对MEF进行简单的介绍.本节主要来介绍如何在Asp.Net Mvc3.0中使用MEF. 准 ...

  3. 基础教程:视图中的ASP.NET Core 2.0 MVC依赖注入

    问题 如何在ASP.NET Core MVC Views中注入和使用服务. 解 更新 启动 类来为MVC添加服务和中间件. 添加一项服务 添加一个Controller,返回 ViewResult. 添 ...

  4. .NET CORE 2.0之 依赖注入在类中获取IHostingEnvironment,HttpContext

    在.NET CORE 中,依赖注入非常常见, 在原先的 HttpContext中常用的server.Mappath已经么有了如下: HttpContext.Current.Server.MapPath ...

  5. Asp.Net Mvc3.0(MEF依赖注入理论)

    前言 Managed Extensibility Framework(MEF)是.NET平台下的一个扩展性管理框架,它是一系列特性的集合,包括依赖注入(DI)等.MEF为开发人员提供了一个工具,让我们 ...

  6. ASP.NET MVC3使用Unity2.0实现依赖注入(转载和扩展)

    http://note.youdao.com/share/?id=53252d0f897e0e109aadd296a1682354&type=note

  7. 05、NetCore2.0依赖注入(DI)之Web应用启动流程管理

    05.NetCore2.0依赖注入(DI)之Web应用启动流程管理 在一个Asp.net core 2.0 Web应用程序中,启动过程都做了些什么?NetCore2.0的依赖注入(DI)框架是如何管理 ...

  8. 谈谈php里的IOC控制反转,DI依赖注入

    理论 发现问题 在深入细节之前,需要确保我们理解"IOC控制反转"和"DI依赖注入"是什么,能够解决什么问题,这些在维基百科中有非常清晰的说明. 控制反转(In ...

  9. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(7):装配SpringBean·依赖注入装配

    一.依赖注入的三种方式      在实际环境中实现IoC容器的方式主要分为两大类,一类是依赖查找,依赖查找是通过资源定位,把对应的资源查找回来.另一类则是依赖注入.一般而言,依赖注入可分为3中方式: ...

随机推荐

  1. java之String字符串根据指定字符转化为字符串数组

    public static void main(String[] args){ String str="护肤,药品,其他"; String temp[]; temp=str.spl ...

  2. 拼凑一个ABP VNext管理后台

    介绍 本项目前后端分离,后端采用ABP VNext框架,前端Vue. 项目地址: https://github.com/pojianbing/AuthCenter 目前包含的模块有: 身份认证管理 I ...

  3. win11拖动窗口造成崩溃的问题

    问题描述 拖动窗口,随机概率出现 屏幕闪烁 屏幕黑屏 屏幕瞬间分屏 解决方法 windowes11贴吧大神给的方案 1,按下 win键+R 输入 regedit 进入注册表,进入以下路径:计算机\HK ...

  4. MFC---简介、编码、结构和消息响应

    MFC简介 MFC是微软基础类库的简称,是微软公司实现的一个c++类库,主要封装了大部分的windows API函数 在MFC中,可以直接调用 windows API,同时需要引用对应的头文件或库文件 ...

  5. java的collection类

    collection来源于java.util包. Collection 接口常用的方法 size():返回集合中元素的个数 add(Object obj):向集合中添加一个元素 addAll(Coll ...

  6. Java语言学习day01--6月28日

    Java语言学习day01一:Java概述 1.Java语言发展史 任职于太阳微系统的 詹姆斯·高斯林 等人于1990年代初开发Java语言的雏形,最初被命名为 Oak ,目标设置在 家用电器等小型系 ...

  7. 2021.11.03 P6175 无向图的最小环问题

    2021.11.03 P6175 无向图的最小环问题 P6175 无向图的最小环问题 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题意: 给定一张无向图,求图中一个至少包含 33 ...

  8. 2021.07.17 P3177 树上染色(树形DP)

    2021.07.17 P3177 树上染色(树形DP) [P3177 HAOI2015]树上染色 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 重点: 1.dp思想是需要什么,维护 ...

  9. Java函数的学习

    函数的定义 - 定义的位置:定义在类的内部 - 组成部分: 函数修饰符 类型 函数名(形式参数){ 局部变量: 注释: 函数体: } 函数的调用 - 调用函数时使用 : `函数名():` - 函数在执 ...

  10. spring4+springmvc+springdataJPA+hibernate4+Junit4整合懒加载问题

    文章目录 技术交流 #摘要 本文主要是为了解决"spring4+springmvc+springdataJPA+hibernate4+junit4整合",注解了OneToMany. ...