# AbpVNext_Init **Repository Path**: tangss_695/abpvnext_init ## Basic Information - **Project Name**: AbpVNext_Init - **Description**: 带你一步一步搭建AbpVNext项目,本篇笔记包含了3%的知识点+80%的后端代码+10%的前端代码+7%的异常处理解决方案,开发过程中遇到的问题,在第七章节的“异常处理”都详细分析原因及给出解决方案。 - **Primary Language**: C# - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-09-05 - **Last Updated**: 2024-09-06 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 一、前言 本项目是根据B站上的学习资源(https://www.bilibili.com/video/BV1Hr4y1P78D?p=1&vd_source=bad95ca6359389d05c64799ee99a25be)一步步搭建AbpVNext项目过程中做的笔记,本篇笔记包含了3%的知识点+80%的后端代码+10%的前端代码+7%的异常处理解决方案,教你怎么一步一步搭建AbpVNext项目,开发过程中遇到的问题,在第七章节的“异常处理”都详细分析原因及给出解决方案。 # 二.DDD领域驱动设计 DDD(Domain-Driven Design,领域驱动设计)是一种软件开发方法,它强调软件系统设计应该以问题领域为中心,而不是技术实现为主导。DDD通过一系列手段如统一语言、业务抽象、领域划分和领域建模等来控制软件复杂度,主要用来指导如何解耦业务系统、划分业务模块、定义业务领域模型及其交互。 DDD 4W | 4W | 说明 | |----|----| | Why | 为了应对软件核心的复杂性,降低沟通成本,提供面向对象分析设计的银弹(万能锁匙),用边界来解决规模问题 | | When | 复杂的、不熟悉的 | | What | 是一个面向对象分析设计的延伸,以领域为核心,贯空需求-设计-开发----还对代码落地做了安排 | | How | 应对软件复杂性之道 | # 三、其他 ## 1.依赖注入模式 | 模式 | 说明 | 生命周期 | |----|----|----| | AddSingleton | 每次都是获得同一个实例, 单一实例模式:单一实例对象对每个对象和每个请求都是相同的,可以说是不同客户端不同请求都是相同的 | 项目启动-项目关闭,相当于静态类只会有一个 | | AddScoped | 对于同一个请求返回同一个实例,不同的请求返回不同的实例,作用域模式:作用域对象在一个客户端请求中是相同的,但在多个客户端请求中是不同的 | 请求开始-请求结束,在这次请求中获取的对象都是同一个 | | AddTransient | 每次service请求都是获得不同的实例,暂时性模式:暂时性对象始终不同,无论是不是同一个请求(同一个请求里的不同服务)同一个客户端,每次都是创建新的实例 | 请求获取-(GC回收-主动释放),每一次获取的对象都不是同一个 | ## 2.好用的快捷键 | 快捷键 | 使用说明 | |----|----| | Tab | 类名后打一个空格,再按“Tab”,会自动输出给类声明的变量名 | | Alt+Enter | 构造函数后,按“Alt+Enter”,就会自动创建类成员变量,并对该变量进行赋值 | | Ctrl+R+R | 鼠标选中类名,选中“Ctrl+R+R”,会出现重命名对话框,修改类名后,点击保存,类名和文件名会一起修改为重命名后的类名。 | | prop | 输入“prop”,再按“Tab”会生成一个属性。 | | ctor | 在类里输入“ctol”,会建一个默认的构造函数。 | ## 3.资源地址 | 类型 | 地址 | | ------------------------- | ------------------------------------------------------------ | | 视频教程 | https://www.bilibili.com/video/BV1Hr4y1P78D/?spm_id_from=333.337.search-card.all.click&vd_source=bad95ca6359389d05c64799ee99a25be | | Abp官网 | https://abp.io/ | | Abp文档 | https://abp.io/docs/latest/ | | vue.js官网 | https://cn.vuejs.org/guide/quick-start.html | | vue.js直接通过 CDN | https://unpkg.com/vue@3/dist/vue.global.js | | axios.js官网 | https://www.axios-http.cn/docs/intro | | axios.js使用 jsDelivr CDN | https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js | | axios.js使用 unpkg CDN | https://unpkg.com/axios/dist/axios.min.js | | Element-UI官网 | https://element.eleme.cn/#/zh-CN | | Element-UI 使用CDN | | # 四、AbpVNext新项目搭建 ## 1.进入首页 进入官网(https://abp.io/),点击“开始” ![](images/1.png) ## 2.安装ABP CLI脚手架 ABP CLI 是一个命令行界面, 用于自动执行基于 ABP 的解决方案的一些常见任务. 首先, 你需要使用以下命令安装 ABP CLI: | 操作 | 命令 | 说明 | |----------|--------------------------------------------|--------------------| | 安装 | dotnet tool install -g Volo.Abp.Studio.Cli | | | 更新 | dotnet tool update -g Volo.Abp.Studio.Cli | 如果已安装需要更新 | ## 3.创建一个“BookStore”项目 ![](images/2.png) ![](images/3.png) 值得一提的是此页面上的选项,不同的配置会影响到不同的架构、结构和工具。 | 项目名称 | 说明 | | | ------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | | Project name | 是 Visual Studio 解决方案(.sln文件)的名称,也是项目的根命名空间。 | | | Project type | 有两个选项,如下所示: | | | | 选项 | 说明 | | | Module | 模板用于创建可重用的应用模块。 | | | Application | 模板用于构建 Web 应用程序。 | | UI Framework | UI 框架选项如下: | | | | 选项 | 说明 | | | Angular | | | | Blazor Server | | | | MVC | | | | Blazor WebAssembly | | | | Maui Blazor | | | | None | | | Database Provider | 数据库提供程序选项如下: | | | | 选项 | 说明 | | | Entity Framework Core | 如果选择Entity Framework Core选项,则可以使用 EF Core 支持的任何 DBMS。 | | | MongoDB | | 执行的命令: | 说明 | 命令 | |----------|----------------------------------------------| | 新建项目 | abp new BookStore -m none --theme basic -csf | ## 4.“BookStore”项目结构 以下是 ABP vNext 的常见目录结构和说明: ### 4.1.src目录 包含应用程序的所有源代码和解决方案文件。 | 类型 | 说明 | | |----|----|----| | Domain | Domain(领域) 划分为两个项目,Domain.Share 和 Domain | | | | 项目 | 说明 | | | BookStore.Domain | 定义领域模型和业务逻辑的代码,包含实体、仓储接口、领域服务接口及其实现和其他领域对象。Domain 包依赖于 Domain.Shared 包。 | | | BookStore.Domain.Share | 包含常量、枚举和其他类型,它不能包含实体、存储库、域服务或任何其他业务对象。可以安全地与模块中的所有层使用。此包也可以与第三方客户端使用。 | | Infrastructure | Infrastructure(基础设施) 为每个orm/数据库集成创建一个独立的集成包, 比如Entity Framework Core 和 MongoDB | | | | 项目 | 说明 | | | BookStore.EntityFrameworkCore | 包含针对 Entity Framework Core 的数据访问代码,包括数据库上下文和实体配置等。依赖 Domain ,映射Domain对象(实体和值类型)到数据库表(ORM)并实现在Domain中定义的仓储接⼝。 | | Application | Application(应用服务) 划分为两个项目 Application.Contracts 和 Application | | | | 项目 | 说明 | | | BookStore.Application.Contracts | 包含应用服务接口和相关的数据传输对象(DTO).。Application contract 包依赖于 Domain.Shared 包。 | | | BookStore.Application | 用于定义应用程序层的代码,包括应用服务和应用层的接口和实现。Application 包依赖于 Domain 包和 Application.Contracts 包 | | HTTP | 为模块开发REST风格的HTTP API,为每个应用服务创建一个Controller (通常通过实现其接口)。这些控制器使用应用服务接口来委托操作。它根据需要配置路由,HTTP方法和其他与Web相关的东西 | | | | 项目 | 说明 | | | BookStore.HttpApi | 用于定义 Web API 控制器和接口。只依赖于 Application.Contracts 包. 不要依赖 Application 包。 | | | BookStore.HttpApi.Client | 创建一个为HTTP API包提供客户端服务的HTTP API Client包,这些客户端服务将应用服务接口实现远程端点的客户端。HTTP API Client 包仅依赖于 Application.Contracts 包,使用ABP框架提供的动态代理HTTP C#客户端的功能 | | Web | 包含页面,视图,脚本,样式,图像和其他UI组件,Web 包仅依赖于 HttpApi 包 | | | | 项目 | 说明 | | | BookStore.Web | 包含 Web 应用程序的代码,包括 MVC 控制器、视图和客户端脚本等。 | ### 4.2.test目录 包含应用程序的单元测试、集成测试和端到端测试。 | 项目 | 说明 | |----|----| | BookStore.Domain.Tests | 用于定义领域模型和领域服务的单元测试。 | | BookStore.EntityFrameworkCore.Tests | 包含基于 Entity Framework Core 的数据访问的单元测试。 | | BookStore.Application.Tests | 包含应用服务和应用层的单元测试。 | | BookStore.Web.Tests | 包含 Web 控制器和接口的集成测试。 | ### 4.3.其他 | 目录/文件 | 说明 | |----|----| | wwwroot | 包含 Web 应用程序的静态资源,如样式表、图像和客户端脚本文件。 | | global.json | 定义项目的全局属性和 SDK 版本。 | | BookStore.sln | Visual Studio 解决方案文件,用于管理项目和项目之间的依赖关系。 | # 五、AbpVNext使用模板新建项目 ## 1.修改数据库连接 | 项目 | 文件 | 配置 | |----------------------|------------------|-----------------------------| | BookStore.DbMigrator | appsettings.json | ConnectionStrings-\>Default | | BookStore.Web | appsettings.json | ConnectionStrings-\>Default | ![](images/4.png) ## 2.初始化数据库 ### 2.1.运行“BookStore.DbMigrator”项目 将“BookStore.DbMigrator”设为启动项目: ![](images/5.png) 点击【调试】-\>【开始执行(不调试)】,运行结果如下: ![](images/6.png) 运行成功后,数据库中多了一个“BookStore”库。 ![](images/7.png) ### 2.2.运行“BookStore.EntityFrameworkCore”项目 点击【工具】-\>【NuGet包管理器】-\>【程序包管理器控制台】,将项目切换到“BookStore.EntityFrameworkCore”,输入命令: | 操作 | 命令 | |------------------------------------|----------------------| | ~~初始化数据库(旧AbpVNext用到)~~ | ~~Add-Migration i1~~ | | 更新数据库 | update-database | 运行结果如下: ![](images/8.png) ### 2.3.运行项目 ![](images/9.png) # 六、AbpVNext自定义项目   ## 1.【MyBookStore】解决方案 新建空白解决方案“MyBookStore”。 ## 2.【MyBookStore.Web】项目 新建一个MVC项目“MyBookStore.Web”。 ![](images/10.png) ### 2.1.新建项目 新建一个MVC项目“MyBookStore.Web”项目 ### 2.2.引用包 引用“Volo.Abp.AspNetCore.Mvc”包 ### 2.3.新建“MyBookStoreWebModule.cs”类 添加“MyBookStoreWebModule.cs”类,添加对“AbpAspNetCoreMvcModule”模块的依赖,继承自“AbpModule”,重写“ConfigureServices”和“OnApplicationInitialization”方法,代码如下: ![](images/11.png) ![](images/12.png) DependsOn是一个特性,负责帮我们引入所需要依赖的模块。 ### 2.4.修改“Program.cs”文件 修改“Program.cs”文件,效果如下: ![](images/13.png) ### 2.5.测试【HomeController】 #### 1).增加【IUserService】接口: ![](images/14.png) #### 2).增加【UserService】类: ![](images/15.png) #### 3).修改“MyBookStoreWebModule.cs”文件: ![](images/16.png) #### 4).修改“HomeController.cs”文件: ![](images/17.png) 在构建函数中,当输入完“IUserService”,打一个空格再按“Tab”会自动把变量名“userService”自动输出出来,再按“Alt+Enter”,就会自动创建内部成员变量“\_userService”,并对该变量进行赋值。 #### 5).修改“Home/Index.cshtml”文件: ![](images/18.png) #### 6).运行项目,效果如下: ![](images/19.png) ## 3.【MyBookStore.EntityFrameworkCore】项目 ### 3.1.新建项目 新建“MyBookStore.EntityFrameworkCore”项目。 ![](images/20.png) ### 3.2.引用包 引用“Volo.Abp.AspNetCore”、“Volo.Abp.EntityFrameworkCore”和“Volo.Abp.EntityFrameworkCore.SqlServer”包 ### 3.3.添加数据库默认连接 进入【MyBookStore.Web】项目“appsettings.json”文件,添加数据库默认连接 ![](images/21.png) ### 3.4.新建“MyBookStoreDbContext.cs”类 添加“MyBookStoreDbContext.cs”类,继承自“AbpDbContext”,重写构造函数和“OnModelCreating”方法,设置默认连接“ConnectionStringName”,代码如下: ![](images/22.png) ### 3.5.新建“MyBookStoreEntityFrameworkCoreModule.cs”类 添加“MyBookStoreEntityFrameworkCoreModule.cs”类,添加对“AbpEntityFrameworkCoreModule”模块的依赖,继承自“AbpModule”,重写“ConfigureServices”方法,代码如下: ![](images/23.png) ### 3.6.【MyBookStore.Web】项目引用该项目 进入【MyBookStore.Web】项目-\>【依赖包】右键-\>【添加项目引用】,引用【MyBookStore.EntityFrameworkCore】项目 ![](images/24.png) ### 3.7.修改“Program.cs”文件 修改“Program.cs”文件,添加对“MyBookStoreEntityFrameworkCoreModule”的依赖,效果如下: ![](images/25.png) ### 3.8.测试【HomeController】 #### 1).进入【MyBookStore.Web】-\>修改【HomeController】: ![](images/26.png) #### 2).在【HomeController】构造函数中加入断点,运行【MyBookStore.Web】项目,获取到的上下文变量有值: ![](images/27.png) ## 4.【MyBookStore.Domain】项目   ### 4.1.新建项目 新建一个MVC项目“MyBookStore.Domain”项目 ![](images/28.png) ### 4.2.引用包 引用“Volo.Abp.AspNetCore”、“Volo.Abp.Ddd.Domain”包 ### 4.3.修改“MyBookStoreDomainModule.cs”类 #### 1).“Class.cs”改为“MyBookStoreDomainModule.cs”类 鼠标选中“Class”,选中“Ctrl+R+R”,会出现重命名对话框,修改类名后,点击保存,类名和文件名会一起修改为重命名后的类名。 ![](images/29.png) #### 2).“MyBookStoreDomainModule.cs”类内容: 添加对“AbpDddDomainModule”模块的依赖,继承自“AbpModule”,代码如下: ![](images/30.png) ### 4.4.新建“Users”类 新建“Users.cs”类,继承自“Entity”,代码如下: ![](images/31.png) ### 4.5.【MyBookStore.EntityFrameworkCore】项目引用该项目 进入【MyBookStore.EntityFrameworkCore】项目-\>【依赖包】右键-\>【添加项目引用】,引用【MyBookStore.Domain】项目 ![](images/32.png) ### 4.6.引用设计器包 进入【MyBookStore.Web】项目-\>【依赖包】右键-\>【管理Nuget程序包】,添加对“Microsoft.EntityFrameworkCore.Design”包的引用,引用哪个版本,需要查看【MyBookStore.EntityFrameworkCore】项目中【Volo.Abp.EntityFrameworkCore】包使用的“Microsoft.EntityFrameworkCore.Design”包的版本。 | EntityFrameworkCore项目中的版本 | Web项目中的版本 | |-------------------------------------|------------------------| | ![](images/33.png) | ![](images/34.png) | | | ![](images/35.png) | ### 4.7.运行“MyBookStore.EntityFrameworkCore”项目 点击【工具】-\>【NuGet包管理器】-\>【程序包管理器控制台】,将项目切换到“MyBookStore.EntityFrameworkCore”,输入命令: | 操作 | 命令 | |------------------------------------|----------------------| | ~~初始化数据库(旧AbpVNext用到)~~ | ~~Add-Migration i1~~ | | 更新数据库 | update-database | 运行结果如下: ![](images/36.png) ### 4.8.用户表添加一行测试数据 进入数据库【MyBookStore】,添加一行测试数据: ![](images/37.png) ### 4.9.测试【HomeController】   #### 1).进入【MyBookStore.Web】-\>修改【HomeController】: ![](images/38.png) #### 2).运行项目,效果如下: ![](images/39.png) ## 5.【MyBookStore.Application】项目 ### 5.1.新建项目 新建一个MVC项目“MyBookStore.Application”项目 ![](images/40.png) ### 5.2.引用包 引用“Volo.Abp.AspNetCore”、“Volo.Abp.Ddd.Application”,“Volo.Abp.AutoMapper”包 ### 5.3.引用【MyBookStore.EntityFrameworkCore】项目 进入【MyBookStore.Application】项目-\>【依赖包】右键-\>【添加项目引用】,引用【MyBookStore.EntityFrameworkCore】项目 ![](images/41.png) ### 5.4.新建“UserDto.cs”类 添加“UserDto”类,继承自“EntityDto\”,代码如下: ![](images/42.png) ### 5.5.新建“MyBookStoreApplicationAutoMapperProfile.cs”类 新建“MyBookStoreApplicationAutoMapperProfile”类,继承自“Profile”,代码如下: ![](images/43.png) ### 5.6.新建“MyBookStoreApplicationModule.cs”类 添加“MyBookStoreApplicationModule.cs”类,添加对“AbpDddApplicationModule”、“AbpAutoMapperModule”和“MyBookStoreEntityFrameworkCoreModule”模块的依赖,继承自“AbpModule”,代码如下: ![](images/44.png) ### 5.7.新建“IUserAppService”接口 添加“IUserAppService.cs”接口,代码如下: ![](images/45.png) ### 5.8.新建“UserAppService”类 添加“UserAppService.cs”类,继承自“ApplicationService”和“IUserAppService”,代码如下: ![](images/46.png) ### 5.9.【MyBookStore.Web】项目引用Nuget包 引用“Volo.Abp.Autofac”包 ### 5.10. 【MyBookStore.Web】项目引用该项目 进入【MyBookStore.Web】项目-\>【依赖包】右键-\>【添加项目引用】,引用【MyBookStore.Application】项目 ![](images/47.png) ### 5.11. 修改“Program.cs”文件 进入【MyBookStore.Web】项目,修改“Program.cs”文件,代码如下: ![](images/48.png) ### 5.12. 修改“MyBookStoreWebModule.cs”文件 进入【MyBookStore.Web】项目,修改“MyBookStoreWebModule.cs”文件,移除对“MyBookStoreEntityFrameworkCoreModule”的依赖,添加对“MyBookStoreApplicationModule”的依赖,效果如下: ![](images/49.png) ### 5.13. 测试登录(Vue.js)   #### 1).进入【MyBookStore.Web】-\>修改【HomeController】构造函数: ![](images/50.png) #### 2).进入【MyBookStore.Web】-\>修改【HomeController】增加登陆页面和校验接口: ![](images/51.png) #### 3).下载样式文件和脚本文件 | | | |-----------|--------------------------------------------| | 源码 | 地址 | | axios脚本 | https://unpkg.com/axios/dist/axios.min.js | | vue脚本 | https://unpkg.com/vue@3/dist/vue.global.js | #### 4).进入【MyBookStore.Web】-\>增加【Login】登陆视图页面: ![](images/52.png) 说明:当前下载的vue是3.0版本; #### 5).运行项目,效果如下: ![](images/53.png) ### 5.14. 测试登录(视图模型) #### 1).修改“IUserAppService”接口,增加“Login2”方法: ![](images/54.png) #### 2).修改“UserAppService”类,增加“Login2”方法: ![](images/55.png) #### 3).进入【MyBookStore.Web】-\>修改【HomeController】增加“CheckLogin2”接口: ![](images/56.png) #### 4).进入【MyBookStore.Web】-\>修改【Login】登录视图: ![](images/57.png) ![](images/58.png) #### 5).运行项目,效果如下: ![](images/59.png) ### 5.15. 测试登录(Element-UI) #### 1).进入【MyBookStore.Web】-\>修改【HomeController】增加登陆页面: ![](images/60.png) #### 2).下载样式文件和脚本文件 | | | |----|----| | 源码 | 地址 | | axios脚本 | https://unpkg.com/axios/dist/axios.min.js | | vue脚本 | https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js | | element-ui样式 | https://unpkg.com/element-ui/lib/theme-chalk/index.css | | element-icons.woff | https://unpkg.com/element-ui@2.15.14/lib/theme-chalk/fonts/element-icons.woff ​ | | element-icons.ttf | https://unpkg.com/element-ui@2.15.14/lib/theme-chalk/fonts/element-icons.ttf | | element-ui脚本 | https://unpkg.com/element-ui/lib/index.js | #### 3).进入【MyBookStore.Web】-\>增加【ELogin】登陆视图页面: ![](images/61.png) ![](images/62.png) ![](images/63.png) ![](images/64.png) #### 4).运行项目,效果如下: ![](images/65.png) # 七、异常处理 ## 1.【MyBookStore.EntityFrameworkCore】下运行“update-database”出现异常   ### 1.1.出现异常1 出现异常: Your startup project 'MyBookStore.Web' doesn't reference Microsoft.EntityFrameworkCore.Design. This package is required for the Entity Framework Core Tools to work. Ensure your startup project is correct, install the package, and try again. ![](images/66.png) 解决方案: 在启动项目【MyBookStore.Web】中引用“Microsoft.EntityFrameworkCore.Design”包引用。 ### 1.2.出现异常2 出现异常: The Entity Framework tools version '8.0.4' is older than that of the runtime '8.0.8'. Update the tools for the latest features and bug fixes. See https://aka.ms/AAc1fbw for more information. ![](images/67.png) 原因:【MyBookStore.Web】项目与【MyBookStore.EntityFrameworkCore】项目中的“Microsoft.EntityFrameworkCore.Design”包版本不一致,需要【MyBookStore.Web】项目中的引用包改为一致。 | EntityFrameworkCore项目中的版本 | Web项目中的版本 | |-------------------------------------|------------------------| | ![](images/68.png) | ![](images/69.png) | | | ![](images/70.png) | 解决方案: 在启动项目【MyBookStore.Web】中引用“Microsoft.EntityFrameworkCore.Design 8.0.4”包引用。 ### 1.3.出现异常3 出现异常: Unable to create a 'DbContext' of type ''. The exception 'No database provider has been configured for this DbContext. A provider can be configured by overriding the 'DbContext.OnConfiguring' method or by using 'AddDbContext' on the application service provider. If 'AddDbContext' is used, then also ensure that your DbContext type accepts a DbContextOptions\ object in its constructor and passes it to the base constructor for DbContext.' was thrown while attempting to create an instance. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728 ![](images/71.png) 解决方案: ![](images/72.png) ## 2.异常:Value cannot be null. (Parameter 'provider') ![](images/73.png) 原因分析:在AbpVNext中需要用“Autofac”替代.NetCore自带的容器。 解决方案:进入【MyBookStore.Web】项目,引用Nuget包“Volo.Abp.Autofac”,再修改“Program.cs”文件,代码如下: ![](images/74.png) ## 3.缺少“element-icons.woff”和“element-icons.ttf”二个文件 ![](images/75.png) 解决方案:进入这个网站【https://unpkg.com/browse/element-ui@2.15.14/lib/theme-chalk/】 下载以下二个文件: ![](images/76.png) # 八、尾声 本人邮箱(732320850@qq.com),有需要可以@我互相交流一下技术和经验。