ASP.NET Core使用了大量的DI(Dependency Injection)设计,有用过Autofac或类似的DI Framework对此应该不陌生。
本篇将介绍ASP.NET Core的依赖注入。

DI运作方式

ASP.NET Core的DI是采用Constructor Injection,也就是说会把实例化的物件从建构子传入。例如:

1
2
3
4
5
6
7
8
9
10
public class HomeController : Controller
{
private readonly ISample _sample; public HomeController(ISample sample)
{
_sample = sample;
// ...
}
}

上述的样本,会在HomeController被实例化的时候注入进来。
每个请求都会把Controller实例化,所以从建构子注入,就能确保动作能够使用到被注入进来的_sample。

光看上面的程式码,可能会很困惑ASP.NET Core要如何知道样本的实做类别?
要注入的服务需要在启动中注册实做类别。如下:

1
2
3
4
5
6
7
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<ISample, Sample>();
}
}

如此一来,在ASP.NET核心实例化控制器时,发现建构子有ISample这个类型的参数,就把Sample的实例注入给该控制器。

1.建立服务

基本上要注入到服务的类别没什么限制,除了静态类别。
以下范例程式就只是一般的类继承接口:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public interface ISample
{
Guid Id { get; }
} public interface ISampleTransient : ISample
{
} public interface ISampleScoped : ISample
{
} public interface ISampleSingleton : ISample
{
} public class Sample : ISampleTransient, ISampleScoped, ISampleSingleton
{
private Guid _id; public Sample()
{
_id = Guid.NewGuid();
} public Guid Id => _id;
}

2.注册服务

注册服务有分三种方式:

  1. 瞬态
    每次注入时,重新都new一个新的实体。
  2. 作用域
    每个请求都重新new一个新的实体。
  3. 辛格尔顿
    程式启动后会new一个实体。也就是运行期间只会有一个实体。
1
2
3
4
5
6
7
8
9
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<ISampleTransient, Sample>();
services.AddScoped<ISampleScoped, Sample>();
services.AddSingleton<ISampleSingleton, Sample>();
}
}

第一个泛型为注入的类型,建议用interface来包装,这样在才能把相依关系拆除。
第二个泛型为实做的类别。

服务实例产生方式:

  • A为单身人士
  • B为Scoped
  • C为瞬态

3.注入服务

被注入的服务可以在Controller,View,Filter,Middleware或自订的服务等使用,只要是透过ASP.NET Core产生实例的类别,都可以在建构子定义
模态注入。此篇我只用Controller,服务,查看做为范例。

3.1 调节器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class HomeController : Controller
{
public readonly ISampleTransient _sampleTransient;
public readonly ISampleScoped _sampleScoped;
public readonly ISampleSingleton _sampleSingleton; public HomeController(ISampleTransient sampleTransient, ISampleScoped sampleScoped, ISampleSingleton sampleSingleton)
{
_sampleTransient = sampleTransient;
_sampleScoped = sampleScoped;
_sampleSingleton = sampleSingleton;
} public IActionResult Index()
{
var message = $"<tr><td>Transient</td><td>{_sampleTransient.Id}</td></tr>"
+ $"<tr><td>Scoped</td><td>{_sampleScoped.Id}</td></tr>"
+ $"<tr><td>Singleton</td><td>{_sampleSingleton.Id}</td></tr>";
return View(model: message);
}
}

3.2 服务

1
2
3
4
5
6
7
8
9
10
11
12
13
public class SampleService
{
public ISampleTransient SampleTransient { get; private set; }
public ISampleScoped SampleScoped { get; private set; }
public ISampleSingleton SampleSingleton { get; private set; } public SampleService(ISampleTransient sampleTransient, ISampleScoped sampleScoped, ISampleSingleton sampleSingleton)
{
SampleTransient = sampleTransient;
SampleScoped = sampleScoped;
SampleSingleton = sampleSingleton;
}
}

注册SampleService

1
2
3
4
5
6
7
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<SampleService, SampleService>();
}
}

第一个泛型也可以是类别,不一定要是介面。

3.3 视图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@model  string

@using MyWebsite

@inject ISampleTransient sampleTransient
@inject ISampleScoped sampleScoped
@inject ISampleSingleton sampleSingleton
@inject SampleService sampleService <table>
<colgroup>
<col width="100" />
</colgroup>
<tbody>
<tr><th colspan="2">Controler</th></tr>
@Html.Raw(Model) <tr><th colspan="2">Service</th></tr>
<tr><td>Transient</td><td>@sampleService.SampleTransient.Id</td></tr>
<tr><td>Scoped</td><td>@sampleService.SampleScoped.Id</td></tr>
<tr><td>Singleton</td><td>@sampleService.SampleSingleton.Id</td></tr> <tr><th colspan="2">View</th></tr>
<tr><td>Transient</td><td>@sampleTransient.Id</td></tr>
<tr><td>Scoped</td><td>@sampleScoped.Id</td></tr>
<tr><td>Singleton</td><td>@sampleSingleton.Id</td></tr>
</tbody>
</table>

执行结果

  1. Transient如预期,每次都不一样。
  2. Soped在同一个Requset中,不论是在哪边被注入,都是同样的实体。(红色箭头)
  3. Singleton不管Requset多少次,都会是同一个实体。(蓝色方框)

本文地址:https://blog.johnwu.cc/article/asp-net-core-dependency-injection.html
作者博客:John Wu

ASP.NET Core 的 Dependency Injection的更多相关文章

  1. 理解ASP.NET Core - [03] Dependency Injection

    注:本文隶属于<理解ASP.NET Core>系列文章,请查看置顶博客或点击此处查看全文目录 依赖注入 什么是依赖注入 简单说,就是将对象的创建和销毁工作交给DI容器来进行,调用方只需要接 ...

  2. ASP.NET Core 中文文档 第三章 原理(10)依赖注入

    原文:Dependency Injection 作者:Steve Smith 翻译:刘浩杨 校对:许登洋(Seay).高嵩 ASP.NET Core 的底层设计支持和使用依赖注入.ASP.NET Co ...

  3. Working with Data » 使用Visual Studio开发ASP.NET Core MVC and Entity Framework Core初学者教程

    原文地址:https://docs.asp.net/en/latest/data/ef-mvc/intro.html The Contoso University sample web applica ...

  4. 【翻译】在Visual Studio中使用Asp.Net Core MVC创建你的第一个Web API应用(一)

    HTTP is not just for serving up web pages. It's also a powerful platform for building APIs that expo ...

  5. [转]【翻译】在Visual Studio中使用Asp.Net Core MVC创建你的第一个Web API应用(一)

    本文转自:https://www.cnblogs.com/inday/p/6288707.html HTTP is not just for serving up web pages. It’s al ...

  6. Building simple plug-ins system for ASP.NET Core(转)

    Recently I built plug-ins support to my TemperatureStation IoT solution web site. The code for .NET ...

  7. 【原生态跨平台:ASP.NET Core 1.0(非Mono)在 Ubuntu 14.04 服务器上一对一的配置实现-篇幅1】

    鸡冻人心的2016,微软高产年. build 2016后 各种干货层出不穷. 1 Win10 集成了bash  ,实现了纳德拉的成诺,Microsoft Love Linux!!! 2 跨平台  ,收 ...

  8. Professional C# 6 and .NET Core 1.0 - 40 ASP.NET Core

    本文内容为转载,重新排版以供学习研究.如有侵权,请联系作者删除. 转载请注明本文出处:Professional C# 6 and .NET Core 1.0 - 40 ASP.NET Core --- ...

  9. DI in ASP.NET Core

    .NET-Core Series Server in ASP.NET-Core DI in ASP.NET-Core Routing in ASP.NET-Core Error Handling in ...

随机推荐

  1. 【转载】C#中ArrayList集合类使用Add方法添加元素

    ArrayList集合是C#中的一个非泛型的集合类,是弱数据类型的集合类,可以使用ArrayList集合变量来存储集合元素信息,任何数据类型的变量都可加入到同一个ArrayList集合中,因此使用Ar ...

  2. js进度条源码下载—js进度条代码

    现在很多网站会用到进入网站特效,到网页没有加载完成的时候,会有一个loding特效,加载完了之后才能看到页面,今天就带着做一个js进度条效果,今天要做的效果是纯js进度条加载,没有用到框架,方便大家进 ...

  3. 49.react中使用less

    1.安装less:npm install less less-loader --save 2.webpack.config.js中配置: oneOf: [ {   test: /\.less$/,   ...

  4. 金融finaunce财经

    金融 (经济学术语) 金融是货币资金融通的总称.主要指与货币流通和银行信用相关的各种活动.主要内容包括: 货币的发行.投放.流通和回笼:各种存款的吸收和提取:各项贷款的发放和收回:银行会计.出纳.转账 ...

  5. AI金融:利用LSTM预测股票每日最高价

    第一部分:从RNN到LSTM 1.什么是RNN RNN全称循环神经网络(Recurrent Neural Networks),是用来处理序列数据的.在传统的神经网络模型中,从输入层到隐含层再到输出层, ...

  6. Android 使用traceView

    Android在做性能优化的时候需要使用traceView进行检测,traceView可以详细的记录下线程执行的时间让我们在做优化的时候可以清楚优化哪些内容.首先我们需要使用这个traceView,在 ...

  7. MySql操作命令创建学生管理系统

    1.创建学生管理系统数据库xscj create detabase 数据库名: 2.打开数据库 use 数据库名: //创建数据库之后,该数据库不会自动成为当前数据库需要用use来指定 3.创建表名 ...

  8. Mac安装vscode IDE 撸nodejs代码

    1. vscode官网地址:https://code.visualstudio.com   找到mac对应的下载地址,下载后的文件是 zip压缩包,解压后将文件拖到Application目录下即可. ...

  9. Linux系统的安装-2019-11-11

    1.虚拟机上的每个步骤 2,加载光盘镜像   3.内核相关的信息: Linux Redhat-7-43.cn 3.10.0-957.27.2.el7.x86_64 主版本号:3 次版本号:10[奇数为 ...

  10. Linux——Pxe+Nfs+Kickstart自动部署安装Centos7.4

    PXE简介 PXE,全名Pre-boot Execution Environment,预启动执行环境:通过网络接口启动计算机,不依赖本地存储设备(如硬盘)或本地已安装的操作系统:由Intel和Syst ...