尝试使用
ASP.Net Core
开发web应用程序一段时间了,感觉ASP.Net core
不论是开发体验还是各方面都很优秀,整理笔记,便于后面使用时翻看。
Init
初始化官方文档 dotnet 指令
新建项目
dotnet new web
官方文档 dotnet new
使用Visual Studio 2017 直接新建 .NET Core 项目
此处以一个Web API 项目为例, 针对不太大的项目,采用了一个划分为三层的结构。
XXXX.Core
项目核心 (Class Library)XXXX.Infrastructure
基础设施 (Class Library)XXXX.Api
API主体 (dotnet
生成)其中,Infrastructure 依赖于Core ,API主体依赖于Core 和 Infrastructure。
XXX.csproj
每个 dotnet core
项目都会有一个唯一的xxx.csproj
,区别于一整个解决方案一个唯一的xxx.sln
,解决方案内的每一个项目,包括类库等,都有自己唯一的xxx.csproj
,这是标识了当前项目的内容,依赖,和配置信息等构建这个项目一切内容的一个 xml
文档。
Nuget
,其他类库等)Program.cs
主程序入口。有一个 Main 方法。
事实上,Web 项目的本质就是一个 Console 项目,在Main 中声明和创建了一个 IWebHost
来作为 ASP.NET Core
应用的核心,其中包含了配置信息,和Kestrel
服务。
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().RUn();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
Startup.cs
ASP.NET Core
有两个配置文件,上面我们也看到了,在Program.cs
中进行了一些列的配置,同样,也注意到,后面使用了.UseStartup<Startup>()
来调用Startup.cs
中的配置文件。
Program 主要进行基础设施的配置,通常不会随便变化:
Startup 主要配置自定义行为,需要经常进行修改
Startup.ConfigureServices 的主要功能是
注册服务
,即注册服务到IoC容器。 关于 dotNet core 中的依赖注入和 IoC 可以参考 - ASP.NET Core中的依赖注入(1):控制反转(IoC)
ASP.NET Core 应用启动时读取ASPNETCORE_ENVIRONMENT
这个环境变量的值, 并保存在IHostingEnvironment.EnvironmentName
里。
环境变量 ASPNETCORE_ENVIRONMENT 可以是任何值. ASP.NET Core里默认带了三个值:
如果ASPNETCORE_ENVIRONMENT没有被设置, 那么会默认取值为Production.
开发时和生产时的配置肯定会有不同,通常设置不同的环境配置,来切换调试,设置方法:
environmentVariables
Debug -> Profile 和 Environment Variables
Properties\launchSettings.json
来进行设置, 这里的值会覆盖系统级环境变量的值
ASP.NET Core应用可以为不同的环境定义单独的Startup类/方法, 并在运行时选择适当的Startup类/方法
使用基于环境的类:Startup{环境名称}
在Program里配置IWebHostBuilder时使用UseStartup(IWebHostBuilder, String)而不是- UseStartup(IWebHostBuilder).String参数是StartupXxx所在的Assembly的名字.
列举几个 dotNet core 常用的服务和开发技巧,并介绍安装使用过程:
微软建议所有的 ASP.NET Core应用都调用HTTPS重定向中间件, 来把所有的HTTP请求重定向为HTTPS.
Startup里:
微软建议在生产环境下启用HSTS. Startup里:
Entity Framework (EF) Core 是轻量化、可扩展和跨平台版的常用 Entity Framework 数据访问技术。
EF Core 可用作对象关系映射程序 (O/RM),以便于 .NET 开发人员能够使用 .NET 对象来处理数据库,这样就不必经常编写大部分数据访问代码了。
EF Core 支持的数据集及其Nuget包参阅 https://docs.microsoft.com/zh-cn/ef/core/providers/index
安装:
Microsoft.EntityFrameworkCore.Design
Microsoft.EntityFrameworkCore.Sqlite
(此处使用SqlLite 作为本地Dev 环境数据库)services.AddDbContext<XxxContext>(…)
参考上面的目录结构,Entities放在BlogDemo.Core项目.Context放在BlogDemo. Infrastructure项目. 在BlogDemo. Api项目进行注册配置.
数据库迁移:
使用dotnet cli 迁移:参考 https://docs.microsoft.com/zh-tw/ef/core/miscellaneous/cli/dotnet
实现 Entity 约束有两种方法:
为什么要使用Repository模式?
DIP, 也就是SOLID里面的D, 高级别的模块不应该依赖于低级别的模块, 它们都应该依赖于抽象
ASP.NET Core 服务注册生命周期
按照最初提出者的介绍,它是衔接数据映射层和域之间的一个纽带,作用相当于一个在内存中的域对象集合。客户端对象把查询的一些实体进行组合,并把它们提交给Repository。对象能够从Repository中移除或者添加,就好比这些对象在一个Collection对象上就行数据操作,同时映射层的代码会对应的从数据库中取出相应的数据。从概念上讲,Repository是把一个数据存储区的数据给封装成对象的集合并提供了对这些集合的操作。在领域驱动设计中,我们有个集合(aggregate)的概念, 通常我们是对于domain的每个集合会对应的定义一个repository。也就说,并不是每个实体都会有对应的一个repository。
简说了,主要作用是在数据持久化过程中,数据提交,确保数据的完整性,对象使用确保同一上下文对象。如果有异常,提供回滚。
为什么要使用Unit of Work模式?
Uow 和 Repository模式 的关系即:
工作单元服务于仓储,并在工作单元中初始化上下文,为仓储单元提供上下文对象,由此确保同一上下文对象。