1. 汇总
ABP-Book Store Application中文讲解-汇总-CSDN博客
2. 前一章
ABP-Book Store Application中文讲解 - 前期准备 - Part 3:Acme.BookStore项目模块详解
项目之间的引用关系。
目录
1.1.1 后端aspnet-core packages安装
1.2 利用Visual Sutio 2022和 npm安装
1.2.1 后端aspnet-core packages安装
2.3 利用EF Core创建Books表,初始化数据,更新数据
2.3.1. 利用VS自带的Package Manager Console(推荐)
2.4.2 利用AutoMapper创建Entity和Dto的映射关系
2.4.3 创建IBookAppService和BookAppService
1. 安装依赖项
如果你执行abp new命令时候附加了--dont-run-install-libs或者你是从git或者其他代码仓库下载下来的代码,此时需要你进行相关packages的安装 (API端和angular端)。
此时有两种方式:(推荐用第二种)
1.1 利用abp命令进行安装
1.1.1 后端aspnet-core packages安装
选择目录(Acme.BookStore\aspnet-core),然后直接输入cmd,或者打开cmd.exe,然后定位到你的Acme.BookStore\aspnet-core目录。
1.1.2 前端angular packages安装
即安装node_modules.
1.2 利用Visual Sutio 2022和 npm安装
1.2.1 后端aspnet-core packages安装
Visual Studio 2022打开Acme.BookStore\aspnet-core\Acme.BookStore.sln. 然后点击F6编译即可自动安装packages。
1.2.2 前端angular packages安装
此处有两种方式:
1.在vs code中运行npm install
用vs code打开angular文件夹,然后ctrl+`快捷键打开terminal,输入npm install即可安装。
如果提示安装失败,多数是因为node.js版本不对或者可以通过删除node.js (本人机器中用的nvm,所以可以找到对应的nodejs版本后,删除里面的npm.ps1文件即可)中的npm.ps1文件。
2. 在cmd.exe中运行npm install
打开文件夹angular,选中路径后输入cmd,敲击回车,快速定位到angular目录,此时可以利用nvm list查看下当前的node.js版本。
我本机安装的是最新版本的node.js,angular项目的angular版本是19。
此时可以直接运行npm install 进行packages的安装。
2. Creating the Server Side
2.1 创建Book实体
Domain层包括以下两类分开的类库:
Acme.BookStore.Domain.Shared:包括常量constants,枚举类型enums等。
Acme.BookStore.Domain: 包括实体类entities, 域服务domain service(例如:BookManager.cs)等。
ABP针对Entities有两个base class:AggregateRoot和Entity。AggregateRoot是DDD(domain driven design)概念,它可以被认为是直接查询和处理的根实体(参照 entities document)
entities是DDD的核心概念,一个entity对应关系型数据库的一张表。
创建entity的时候可以选择继承Entity<TKey>或者自己实现IEntity<TKey>接口。
Entity<TKey>
class 用于定义Id
列,TKey是主键数据类型, 你可以定义Guid
,string
,int
,long
, 或者其他你想要的类型。ABP推荐使用Guid,并使用 the IGuidGenerator service去设置值,而不推荐Guid.NewGuid()。
IGuidGenerator被优化为生成有顺序的Guid,这对于关系数据库中的聚集索引至关重要。
public class Book : Entity<Guid> { public string Name { get; set; } public float Price { get; set; } }
在Acme.BookStore.Domain.Shared创建Books目录,然后里面创建BookType枚举类。
namespace Acme.BookStore.Books
{
public enum BookType
{
Undefined = 0,
Adventure,
Biography,
Dystopia,
Fantastic,
Horror,
Science,
ScienceFiction,
Poetry
}
}
创建Books目录,然后里面创建Book类,继承AuditedAggregateRoot并指定主键类型为GUID。
using System;
using Volo.Abp.Domain.Entities.Auditing;
namespace Acme.BookStore.Books
{
public class Book : AuditedAggregateRoot<Guid>
{
public required string Name { get; set; }
public BookType Type { get; set; }
public DateTime PublishDate { get; set; }
public float Price { get; set; }
}
}
创建完成后目录结构如下:
2.2 将Book实体注册到DbSet,并指定数据表名称
因为EF Core是code first设置模式,我们不用手动写sql去创建表,EFCore可以自动帮我们生成。
但是需要我们添加到DbContext中,即添加到Acme.BookStore.EntityFrameworkCore中的BookStoreDbContext.cs。
当执行Add-Migration,然后执行Update-Database会在数据库中生成Books表,如果你想改成Book,需要在OnModelCreating中重命名,代码如下:
DbTablePrefix是一个常量,你可以在BookStoreConsts.cs中进行更改。
按照DDD设置模式,BookStoreConsts.cs应该要创建在Acme.BookStore.Domain.Shared中,但是abp官方却在Acme.BookStore.Domain中创建。
代码中DbSchema默认为null,然后在SQL Server数据库创建表后,表的shcema默认是dbo
2.3 利用EF Core创建Books表,初始化数据,更新数据
此处有两种方式:
2.3.1. 利用VS自带的Package Manager Console(推荐)
1. Tools -> Nuget Package Manager -> Package Manager Console。
2. 选择默认项目(Default project)到Acme.BookStore.EntityFrameworkCore
3. 输入 Add-Migration Created_Book_Entity敲回车 (此处可以输入add-mig后直接敲Tab自动补全Add-Migration)
2.3.2. 利用dotnet ef
打开cmd.exe,指定目录到Acme.BookStore.EntityFrameworkCore,然后输入以下命令敲回车:
dotnet ef migrations add Created_Book_Entity
2.3.3 初始化数据
在Acme.BookStore.Domain中的Data目录下创建BookStoreDataSeederContributor继承IDataSeedContributor
和ITransientDependency。
ITransientDependency是类似于.NET API中的service.AddTransient。 ABP对这个进行了封装,利用autofac自动注册,不用在Program.cs中注册了。
IDataSeedContributor
中有SeedAsync,我们只需要实现它就可以了。此处首先利用IRepository<Book, Guid>判断是否有记录了,如果没有记录就插入一些数据。
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories;
namespace Acme.BookStore.Data
{
public class BookStoreDataSeederContributor : IDataSeedContributor, ITransientDependency
{
private readonly IRepository<Book, Guid> _bookRepository;
public BookStoreDataSeederContributor(IRepository<Book, Guid> bookRepository)
{
_bookRepository = bookRepository;
}
public async Task SeedAsync(DataSeedContext context)
{
if (await _bookRepository.GetCountAsync() <= 0)
{
await _bookRepository.InsertAsync(
new Book()
{
Name = "三体",
Type = BookType.Fantastic,
PublishDate = new DateTime(2006, 5, 20),
Price = 100
},
autoSave: true
);
await _bookRepository.InsertAsync(
new Book()
{
Name = "三体2:黑暗森林",
Type = BookType.Fantastic,
PublishDate = new DateTime(2008, 5, 21),
Price = 100
},
autoSave: true
);
await _bookRepository.InsertAsync(
new Book()
{
Name = "三体3:死神永生",
Type = BookType.Fantastic,
PublishDate = new DateTime(2010, 11, 11),
Price = 100
},
autoSave: true
);
await _bookRepository.InsertAsync(
new Book()
{
Name = "人世间",
Type = BookType.Dystopia,
PublishDate = new DateTime(2017, 12, 11),
Price = 100
},
autoSave: true
);
}
}
}
}
2.3.4 更新数据库
将Acme.BookStore.DbMigrator设置为默认启动项,然后启动运行会自动更新DB到数据库,同时调用BookStoreDataSeederContributor初始化数据。
2.4 创建Application Service
Application Sevice分成两部分:
- Acme.BookStore.Application.Contracts:包括DTOs和Application Service接口
- Acme.BookStore.Application:对Acme.BookStore.Application.Contracts定义的接口的实现
在这一章节我们会实现对Book的增删改查(CRUD),我们可以用ABP封装的CrudAppService进行实现,或者也可以用基本的IRepository (IRepository<Book, Guid>)去实现。
2.4.1 创建Book相关的Dto
在Acme.BookStore.Application.Contracts中创建Books目录,并创建以下类:
BookDto.cs:用户在UI上面显示的内容
CreateUpdateBookDto.cs: 创建和更新Book的Dto
BookDto.cs
using System;
using Volo.Abp.Application.Dtos;
namespace Acme.BookStore.Books
{
public class BookDto : AuditedEntityDto<Guid>
{
public required string Name { get; set; }
public BookType Type { get; set; }
public DateTime PublishDate { get; set; }
public float Price { get; set; }
}
}
CreateUpdateBookDto.cs
Required, StringLengh,DataType用于Validation的校验
using System;
using System.ComponentModel.DataAnnotations;
namespace Acme.BookStore.Books
{
public class CreateUpdateBookDto
{
[Required]
[StringLength(128)]
public string Name { get; set; } = string.Empty;
[Required]
public BookType Type { get; set; } = BookType.Undefined;
[Required]
[DataType(DataType.Date)]
public DateTime PublishDate { get; set; } = DateTime.Now;
[Required]
public float Price { get; set; }
}
}
2.4.2 利用AutoMapper创建Entity和Dto的映射关系
我们需要利用AutoMapper类库将BookDto和Book进行一个映射,即在类BookStoreApplicationAutoMapperProfile中增加以下代码:
如果没有BookStoreApplicationAutoMapperProfile.cs,你可以在Acme.BookStore.Application中创建一个。
完整代码如下截图所示:
CreateMap<Book, BookDto>();
CreateMap<CreateUpdateBookDto, Book>();
2.4.3 创建IBookAppService和BookAppService
在Acme.BookStore.Application.Contracts中的Books目录下创建IBookAppService接口,在Acme.BookStore.Application中的Books目录下创建BookAppService.cs对IBookAppService接口的实现。
注意命名规范,必须是I***AppService和***AppService,否则autofac没法自动生成Restful的API接口。
IBookAppService
如果你不想继承ICrudAppService,你可以直接继承IApplicationService,然后自定义
GetAsync
,GetListAsync
,CreateAsync
,UpdateAsync
andDeleteAsync
using System;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
namespace Acme.BookStore.Books
{
/// <summary>
/// Book Service
/// </summary>
public interface IBookAppService : ICrudAppService<// 定义CRUD方法,里面包括常用的方法: GetAsync, GetListAsync, CreateAsync, UpdateAsync and DeleteAsync
BookDto, // 用于在页面上显示的Book
Guid, // primary key of Book.cs
PagedAndSortedResultRequestDto,// 用于分页和排序
CreateUpdateBookDto>// 用于创建和更新Book的入参
{
}
}
BookAppService
想要获取CrudAppService的源码,可以访问CrudAppService.cs或者ABP的CrudAppService源码-CSDN博客或者 framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services · wzcool/abp - 码云 - 开源中国
using System;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
namespace Acme.BookStore.Books
{
public class BookAppService : CrudAppService<Book, BookDto, Guid, PagedAndSortedResultRequestDto, CreateUpdateBookDto>,
IBookAppService
{
public BookAppService(IRepository<Book, Guid> repository) : base(repository)
{
}
}
}
2.5 Auto API Controller & Swagger UI
在原生的.NET8 API开发中,我们需要再Controller做一个配置,比如设置[HttpGet],[HttpPost], [HttpPut],[HttpDelete],然后在Program.cs中启用Swagger UI ( Swagger UI using the Swashbuckle.AspNetCore)。
但是在ABP框架中,ABP提供了自动配置API controller的功能,只要我们遵循ABP要求的命名规则即可。
命名规则:I***AppService和***AppService
把Acme.BookStore.HttpApi.Host设置为启动项,然后F5启动即可。
https://localhost:<port>/swagger/
如果启动报如下错误,则证明你没有安装Redis。
你可以利用Docker安装,或者直接下载exe安装
Docker安装:
自行百度或者参考Docker + Win 10 学习记录_win10 22h2 docker-CSDN博客
下载zip包
Releases · redis-windows/redis-windows · GitHub