第 3 章 ASP.NET Core 核心特性

3.3 依赖注入

通常情况下,应用程序由多个组件构成,而组件与组件之间往往存在依赖关系

当我们需要获取数据时,通常的做法是实例化依赖的类,然后调用类里面的方法,但是这种依赖方式会增加调用方和被调用方之间的耦合,也会增加应用程序维护成本及灵活性,同时增加了单元测试的难度

为了解决这一问题,需要用到依赖倒置原则,高层不直接依赖低层,两者均依赖抽象

public class Book
{ } public interface IDataService
{
List<Book> GetAllBooks();
} public class DataService : IDataService
{
public List<Book> GetAllBooks()
{
return new List<Book>();
}
} public class DisplayDataService
{
private readonly IDataService _dataService; public DisplayDataService(IDataService dataService)
{
_dataService = dataService;
} public void ShowData()
{
var data = _dataService.GetAllBooks();
}
}

接下来,只需要在实例化 DisplayDataService 的时候,在构造函数传入一个 IDataService 接口的具体实现即可

IDataService dataService = new DataService();
DisplayDataService displayDataService = new DisplayDataService(dataService);

除了构造函数注入之外,还有属性注入和方法注入

当应用程序中有多处要用到依赖注入时,就需要一个专门的类来负责管理创建所需要的类并创建所有它可能要用到的依赖,这个类就是依赖注入容器,也可以称为控制反转容器,IOC 容器

在 ASP.NET Core 中,所有被放入依赖注入容器的类型或组件被称为服务

容器中的服务有两种类型:第一种是框架服务,它们是 ASP.NET Core 框架的组成部分;另一种是应用服务,所有由用户放到容器中的服务都属于这一类

在 ASP.NET Core 内置的依赖注入容器中,服务的生命周期有如下3种类型:

  • Singleton:容器会创建并共享服务的单例,且一直会存在于应用程序的整个生命周期内
  • Transient:每次服务被请求时,总会创建新实例
  • Scoped:在每一次请求时会创建服务的新实例,并在这个请求内一直共享这个实例

3.4 MVC

MVC 是模型、视图、控制器的缩写,它是 Web 应用程序中一种常见的架构模式,最主要的优点是实现了关注点分离

在 ASP.NET Core MVC 框架中,除了 Controller、Model 和 Action 外,它还包括路由、模型绑定、模型验证和过滤器等功能

路由的主要功能是根据预先配置的路由信息对客户端传来的请求进行路由映射,映射完成后,再将请求传给对应的路由处理器处理

对于 ASP.NET Core MVC,定义路由的方法有以下两种:

  • 基于约定的路由
  • 特性路由

基于约定的路由需要在 Startup 类中指明,具体来说,应该在配置 MVC 中间件时来设置路由约定

app.UseMvc(routes =>
{
routes.MapRoute("default",template: "{controller}/{action}");
});

以下约定为 controller 和 action 设置了默认值,参数 id 后面有一个问号,说明这个参数时可选的,在 URL 中有无此项都可以,注意,一个 URL 模板中只能有一个可选参数,并且只能放在最后

app.UseMvc(routes =>
{
routes.MapRoute("default",template: "{controller=Home}/{action=Index}/{id?}");
});

指定参数时,也可以添加约束

app.UseMvc(routes =>
{
routes.MapRoute("default",template: "{controller=Home}/{action=Index}/{id:int}");
});

特性路由只需要在 Controller 类或 Action 方法上添加 [Route] 特性即可

[Route("Home")]
public class HomeController : Controller
{
[Route("Index")]
public IActionResult Index()
{
return View();
}
}

当 Controller 需要依赖其他服务时,通常的做法是使用构造函数注入所需要的服务,当程序运行时,ASP.NET Core 会在创建 Controller 时自动从其依赖注入的容器中获取所有依赖的服务,需要注意的是,所注入的服务必须存在于容器中,否则会发生异常

Action 的返回结果有以下4类:

  • StatusCode
  • ObjectResult
  • 重定向结果
  • 内容结果

模型绑定:将 HTTP 请求中的数据映射到 Action 中参数的过程

ASP.NET Core MVC 模型绑定特性:

  • [FromHeader]
  • [FromQuery]
  • [FromServices]
  • [FromRoute]
  • [FromForm]
  • [FromBody]

还有两个特性用于指明参数是否必须使用绑定:

  • BindRequiredAttribute
  • BindNeverAttribute

模型验证:指数据被使用之前的验证过程,它发生在模型绑定之后

数据注解通常用于验证,只要为类的属性添加需要的数据注解验证特性即可:

  • [Required]
  • [MinLength(10)]
  • [Url]
  • [Range(1,5)]

在 Controller 内的 Action 中,要检查一个对象是否满足指定的条件,只要调用 ModelState.IsVaild 属性,其中 ModelState 是 ControllerBase 类的属性

ASP.NET Core MVC 提供两种创建自定义验证的方法:

  • 创建新特性,并使它继承自 ValidationAttribute 类
  • 使待验证的 Model 实现 IValidatableObject 接口

过滤器:与中间件很相似,在 ASP.NET Core MVC 中,它们能够在某些功能的前后执行,由此形成一个管道

ASP.NET Core MVC 提供了以下5种类型的过滤器:

  • Authorization
  • Resource
  • Action
  • Exception
  • Result

当要创建过滤器时,应该实现 IXXXFilter 或 IAsyncXXXFilter,前者同步,后者异步,实现一个即可

在 startup 种注册过滤器会使它影响到应用中的每个 Action,如果要仅为一个或少数几个 Action 添加过滤器,就得使用特性,ASP.NET Core 为每一种类型的过滤器都定义了相应的特性

如果以特性的方式使用包含依赖项的过滤器时,就会出错,因为在自定义特性的构造函数中定义的接口类型的参数并不是有效的特性参数,此时需要使用 [ServiceFilter] 特性或者 [TypeFilter] 特性,并设置它们的 Type 属性为自定义过滤器类型

[ServiceFilter] 特性与 [TypeFilter] 特性的区别是前者会从容器中获取过滤器实例,而后者不会,它使用 ObjectFactory 对指定的过滤器类型进行实例化,如果使用前者,需要在 Startup 类的 ConfigureServices 方法中将该过滤器添加到容器中

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

欢迎转载、使用、重新发布,但务必保留文章署名 郑子铭 (包含链接: http://www.cnblogs.com/MingsonZheng/ ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。

如有任何疑问,请与我联系 (MingsonZheng@outlook.com) 。

《ASP.ENT Core 与 RESTful API 开发实战》(第3章)-- 读书笔记(中)的更多相关文章

  1. 使用ASP.NET Core构建RESTful API的技术指南

    译者荐语:利用周末的时间,本人拜读了长沙.NET技术社区翻译的技术标准<微软RESTFul API指南>,打算按照步骤写一个完整的教程,后来无意中看到了这篇文章,与我要写的主题有不少相似之 ...

  2. 4类Storage方案(AS开发实战第四章学习笔记)

    4.1 共享参数SharedPreferences SharedPreferences按照key-value对的方式把数据保存在配置文件中,该配置文件符合XML规范,文件路径是/data/data/应 ...

  3. 菜单Menu(AS开发实战第四章学习笔记)

    4.5 菜单Menu Android的菜单主要分两种,一种是选项菜单OptionMenu,通过按菜单键或点击事件触发,另一种是上下文菜单ContextMenu,通过长按事件触发.页面的布局文件放在re ...

  4. [Android]《Android艺术开发探索》第一章读书笔记

    1. 典型情况下生命周期分析 (1)一般情况下,当当前Activity从不可见重新变为可见状态时,onRestart方法就会被调用. (2)当用户打开新的Activity或者切换到桌面的时候,回调如下 ...

  5. 温故知新,使用ASP.NET Core创建Web API,永远第一次

    ASP.NET Core简介 ASP.NET Core是一个跨平台的高性能开源框架,用于生成启用云且连接Internet的新式应用. 使用ASP.NET Core,您可以: 生成Web应用和服务.物联 ...

  6. 快读《ASP.NET Core技术内幕与项目实战》WebApi3.1:WebApi最佳实践

    本节内容,涉及到6.1-6.6(P155-182),以WebApi说明为主.主要NuGet包:无 一.创建WebApi的最佳实践,综合了RPC和Restful两种风格的特点 1 //定义Person类 ...

  7. 零基础ASP.NET Core WebAPI团队协作开发

    零基础ASP.NET Core WebAPI团队协作开发 相信大家对“前后端分离”和“微服务”这两个词应该是耳熟能详了.网上也有很多介绍这方面的文章,写的都很好.我这里提这个是因为接下来我要分享的内容 ...

  8. ASP.NET Core WebApi构建API接口服务实战演练

    一.ASP.NET Core WebApi课程介绍 人生苦短,我用.NET Core!提到Api接口,一般会想到以前用到的WebService和WCF服务,这三个技术都是用来创建服务接口,只不过Web ...

  9. 从 0 使用 SpringBoot MyBatis MySQL Redis Elasticsearch打造企业级 RESTful API 项目实战

    大家好!这是一门付费视频课程.新课优惠价 699 元,折合每小时 9 元左右,需要朋友的联系爱学啊客服 QQ:3469271680:我们每课程是明码标价的,因为如果售价为现在的 2 倍,然后打 5 折 ...

  10. Asp.Net Core 5 REST API - Step by Step

    翻译自 Mohamad Lawand 2021年1月19日的文章 <Asp.Net Core 5 Rest API Step by Step> [1] 在本文中,我们将创建一个简单的 As ...

随机推荐

  1. C#设计模式05——抽象工厂的写法

    C# 抽象工厂是一种创建型设计模式,它提供了一种封装一组相关或相互依赖对象创建的方法.该模式使得客户端能够创建与应用程序所使用的特定工厂无关的对象. 以下是C#抽象工厂5W1H的解释: 1. What ...

  2. python之排序的几种方法

    一.通过sort()可以快速实现数组的排序: 1 a=[2,3,1] 2 a.sort() 3 print(a) 打印返回结果: 二.如果不知道有sort()函数或者一些特殊场景需要排序时,如果解决呢 ...

  3. C++ 不使用虚析构的后果及分析

    很多 C++ 方面的书籍都说明了虚析构的作用: 保证派生类的析构函数被调用,并且使析构顺序与构造函数相反 保证资源能够被正确释放 很久一段时间以来,我一直认为第 2 点仅仅指的是:当派生类使用 RAI ...

  4. 2023年春秋杯网络安全联赛冬季赛-CRYPTO MISC WP

    浅谈:*代表未做出的,赛后复现了一下.本次题目还是挺有意思的,比赛期间做啦俩.题目有很多值得学习的东西.顺便在此记录一下.继续努力吧!! CRYPTO not_wiener(中等) 题目附件 查看代码 ...

  5. [转帖]已整理-shell内置字符串常用操作

    https://www.cnblogs.com/reachos/p/16803672.html bash 里面内置了一些常用的字符串操作: 1.字符串截取 a="abc" ${a: ...

  6. [转帖]关于UNDO

    原文地址:https://www.modb.pro/db/70802?xzs= 一:请描述什么是Oracle Undo. 二:请描述UNDO的作用. 三:请谈谈你对Manual Undo Manage ...

  7. [转帖]kafka压测多维度分析实战

    设置虚拟机不同的带宽来进行模拟压测 ---------kafka数据压测-------------------1.公司生产kafka集群硬盘:单台500G.共3台.日志保留7天.         1. ...

  8. [转帖]ARMv8架构概述、相关技术文档以及ARMv8处理器简介

    ARMv8架构 文章目录 ARMv8架构 参考文档 ARMv8架构的概述 从32位到64位的变化The changes from 32 bits to 64 bits 1,Larger registe ...

  9. 使用influxdb以及Grafana监控vCenter的操作步骤

    1. 下载安装介质 计划telegraf和influxdb 使用rpm包进行安装.Grafana使用docker容器方式安装 下载路径为: https://repos.influxdata.com/r ...

  10. axios取消请求

    为什么会有取消请求-文件上传 比如有这样的场景,在一个弹窗中有文件上传. 当用户进行文件上传的时候,发现不想进行文件上传了,又点击了弹窗中的取消. 那么是不是应该去取消本次的上传操作,此时就需要使用取 ...