《ASP.ENT Core 与 RESTful API 开发实战》(第3章)-- 读书笔记(中)
第 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章)-- 读书笔记(中)的更多相关文章
- 使用ASP.NET Core构建RESTful API的技术指南
译者荐语:利用周末的时间,本人拜读了长沙.NET技术社区翻译的技术标准<微软RESTFul API指南>,打算按照步骤写一个完整的教程,后来无意中看到了这篇文章,与我要写的主题有不少相似之 ...
- 4类Storage方案(AS开发实战第四章学习笔记)
4.1 共享参数SharedPreferences SharedPreferences按照key-value对的方式把数据保存在配置文件中,该配置文件符合XML规范,文件路径是/data/data/应 ...
- 菜单Menu(AS开发实战第四章学习笔记)
4.5 菜单Menu Android的菜单主要分两种,一种是选项菜单OptionMenu,通过按菜单键或点击事件触发,另一种是上下文菜单ContextMenu,通过长按事件触发.页面的布局文件放在re ...
- [Android]《Android艺术开发探索》第一章读书笔记
1. 典型情况下生命周期分析 (1)一般情况下,当当前Activity从不可见重新变为可见状态时,onRestart方法就会被调用. (2)当用户打开新的Activity或者切换到桌面的时候,回调如下 ...
- 温故知新,使用ASP.NET Core创建Web API,永远第一次
ASP.NET Core简介 ASP.NET Core是一个跨平台的高性能开源框架,用于生成启用云且连接Internet的新式应用. 使用ASP.NET Core,您可以: 生成Web应用和服务.物联 ...
- 快读《ASP.NET Core技术内幕与项目实战》WebApi3.1:WebApi最佳实践
本节内容,涉及到6.1-6.6(P155-182),以WebApi说明为主.主要NuGet包:无 一.创建WebApi的最佳实践,综合了RPC和Restful两种风格的特点 1 //定义Person类 ...
- 零基础ASP.NET Core WebAPI团队协作开发
零基础ASP.NET Core WebAPI团队协作开发 相信大家对“前后端分离”和“微服务”这两个词应该是耳熟能详了.网上也有很多介绍这方面的文章,写的都很好.我这里提这个是因为接下来我要分享的内容 ...
- ASP.NET Core WebApi构建API接口服务实战演练
一.ASP.NET Core WebApi课程介绍 人生苦短,我用.NET Core!提到Api接口,一般会想到以前用到的WebService和WCF服务,这三个技术都是用来创建服务接口,只不过Web ...
- 从 0 使用 SpringBoot MyBatis MySQL Redis Elasticsearch打造企业级 RESTful API 项目实战
大家好!这是一门付费视频课程.新课优惠价 699 元,折合每小时 9 元左右,需要朋友的联系爱学啊客服 QQ:3469271680:我们每课程是明码标价的,因为如果售价为现在的 2 倍,然后打 5 折 ...
- 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 ...
随机推荐
- vue结合element-ui实现多层复选框checkbox
1.需求如上图所以: html相关代码如下: 1 <div class="intent-course-wrapper"> 2 <div class="c ...
- proxy配置多个代理
https://blog.csdn.net/h_hongai/article/details/109311786
- 玩转 Helm 之 upgrade
0. 前言 在 玩转 Helm 一文中,简略提到了 Helm upgrade 的策略. 在实际项目开发上,upgrade 多是调研的重点.基于此,这里对 upgrade 继续展开. 1. basic ...
- 一文搞清楚Java中的包、类、接口
写在开头 包.类.接口.方法.变量.参数.代码块,这些都是构成Java程序的核心部分,即便最简单的一段代码里都至少要包含里面的三四个内容,这两天花点时间梳理了一下,理解又深刻了几分. Java中的包 ...
- linux route 命令
route 管理路由表 要实现两个不同的子网之间的通信,需要一台连接两个网络的路由器,或者同时位于两个网络的网关来实现.在Linux系统中,设置路由通常是为了解决以下问题:该Linux ...
- keystore 与 trust store 的区别 及 keytool 常用命令
本文为博主原创,未经允许不得转载: 1. key store 与 trust store 区别 2. java 配置 单向认证与双向认证的过程 3. key store 与 trust store 常 ...
- [springmvc] - 配置文件 springmvc-config.xml 和 web.xml
springmvc-config.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmln ...
- vscode插件 - 浏览器中自动刷新 Live Server
- 03-MySQL字段的数据类型
前言 MySQL 中的字段,主要有四种数据类型: 整型(整数) 小数 字符串类型 时间日期类型 下面来详细讲一讲. 整数类型 整数类型的分类 MySQL中,整型有五种: 迷你整型:tinyint,使用 ...
- [转帖]设置kafka 数据保留时间
https://www.cnblogs.com/gao88/p/12539112.html kafka 单独设置某个topic的数据过期时间kafka 默认存放7天的临时数据,如果遇到磁盘空间小,存放 ...