生成项目
通过用官网的来生成 Get Started | ABP.IO 配上官网地址,需要注意的是,数据库选择Mysql
选择完成后,执行页面上的两条命令
dotnet tool install -g Volo.Abp.Cli
abp new Acme.BookStore -dbms MySQL -csf
生成结束后的内容
单击打开
更改 数据库连接 DbMigrator 模块与Web 模块中的 appsettings.json
"Default": "Server=localhost;Port=3306;Database=BookStore;Uid=root;Pwd=123456;"
到这里基本完成
Book应用
实体类
启动模板中的领域层分为两个项目:
Acme.BookStore.Domain
包含你的实体, 领域服务和其他核心域对象.Acme.BookStore.Domain.Shared
包含可与客户共享的常量,枚举或其他域相关对象.
在解决方案的领域层(Acme.BookStore.Domain
项目)中定义你的实体.
该应用程序的主要实体是Book
. 在Acme.BookStore.Domain
项目中创建一个 Books
文件夹(命名空间),并在其中添加名为 Book
的类,如下所示:
using System;
using Volo.Abp.Domain.Entities.Auditing;namespace Acme.BookStore.Books
{public class Book : AuditedAggregateRoot<Guid>{public string Name { get; set; }public BookType Type { get; set; }public DateTime PublishDate { get; set; }public float Price { get; set; }}
}
Book
实体使用了BookType
枚举. 在Acme.BookStore.Domain.Shared
项目中创建Books
文件夹(命名空间),并在其中添加BookType
:
namespace Acme.BookStore.Books
{public enum BookType{Undefined,Adventure,Biography,Dystopia,Fantastic,Horror,Science,ScienceFiction,Poetry}
}
将Book实体添加到DbContext中
EF Core需要你将实体和 DbContext
建立关联.最简单的做法是在Acme.BookStore.EntityFrameworkCore
项目的BookStoreDbContext
类中添加DbSet
属性.如下所示:
public class BookStoreDbContext : AbpDbContext<BookStoreDbContext>
{public DbSet<Book> Books { get; set; }//...
}
将Book实体映射到数据库表
打开BookStoreDbContext
类的OnModelCreating
方法,为Book
实体添加映射代码:
using Acme.BookStore.Books;
...namespace Acme.BookStore.EntityFrameworkCore
{public class BookStoreDbContext :AbpDbContext<BookStoreDbContext>,IIdentityDbContext,ITenantManagementDbContext{...protected override void OnModelCreating(ModelBuilder builder){base.OnModelCreating(builder);/* Include modules to your migration db context */builder.ConfigurePermissionManagement();.../* Configure your own tables/entities inside here */builder.Entity<Book>(b =>{b.ToTable(BookStoreConsts.DbTablePrefix + "Books",BookStoreConsts.DbSchema);b.ConfigureByConvention(); //auto configure for the base class propsb.Property(x => x.Name).IsRequired().HasMaxLength(128);});}}
}
添加数据迁移
如果你使用Visual Studio, 你也许想要在包管理控制台(PMC)中使用
Add-Migration Created_Book_Entity -c BookStoreDbContext
和Update-Database -Context BookStoreDbContext
命令. 确保Acme.BookStore.Web
是启动项目并且Acme.BookStore.EntityFrameworkCore
是 PMC 的默认项目.
注意:这里会出现 这个错误,在模块中导入 Microsoft.EntityFrameworkCore.Design 包就好了,在web 与 dbmigrator中都要导入,选择与自己版本相对的版本
导入完成后再执行就可以了
刷新数据库 ,可以看到里面已经存在了 bookstore 数据库与表
添加种子数据
在 *.Domain
项目下创建 IDataSeedContributor
的派生类,并且拷贝以下代码:
using System;
using System.Threading.Tasks;
using Acme.BookStore.Books;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories;namespace Acme.BookStore
{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 = "1984",Type = BookType.Dystopia,PublishDate = new DateTime(1949, 6, 8),Price = 19.84f},autoSave: true);await _bookRepository.InsertAsync(new Book{Name = "The Hitchhiker's Guide to the Galaxy",Type = BookType.ScienceFiction,PublishDate = new DateTime(1995, 9, 27),Price = 42.0f},autoSave: true);}}}
}
更新数据库
运行 Acme.BookStore.DbMigrator
应用程序来更新数据库:
把这个模块设为启动项目,直接运行,然后去看数据库。
创建应用程序
应用程序层由两个分离的项目组成:
Acme.BookStore.Application.Contracts
包含你的DTO和应用服务接口.Acme.BookStore.Application
包含你的应用服务实现.
在本部分中,你将创建一个应用程序服务,使用ABP Framework的 CrudAppService
基类来获取,创建,更新和删除书籍.
BookDto
CrudAppService
基类需要定义实体的基本DTO. 在 Acme.BookStore.Application.Contracts
项目中创建 Books
文件夹(命名空间), 并在其中添加名为 BookDto
的DTO类:
using System;
using Volo.Abp.Application.Dtos;namespace Acme.BookStore.Books
{public class BookDto : AuditedEntityDto<Guid>{public string Name { get; set; }public BookType Type { get; set; }public DateTime PublishDate { get; set; }public float Price { get; set; }}
}
- DTO类被用来在 表示层 和 应用层 传递数据.参阅DTO文档.
- 为了在用户界面上展示书籍信息,
BookDto
被用来将书籍数据传递到表示层. BookDto
继承自AuditedEntityDto<Guid>
.与上面定义的Book
实体一样具有一些审计属性.
在将书籍返回到表示层时,需要将Book
实体转换为BookDto
对象. AutoMapper库可以在定义了正确的映射时自动执行此转换. 启动模板配置了AutoMapper,因此你只需在Acme.BookStore.Application
项目的BookStoreApplicationAutoMapperProfile
类中定义映射:
using Acme.BookStore.Books;
using AutoMapper;namespace Acme.BookStore
{public class BookStoreApplicationAutoMapperProfile : Profile{public BookStoreApplicationAutoMapperProfile(){CreateMap<Book, BookDto>();}}
}
CreateUpdateBookDto
在Acme.BookStore.Application.Contracts
项目中创建 Books
文件夹(命名空间),并在其中添加名为 CreateUpdateBookDto
的DTO类:
using System;
using System.ComponentModel.DataAnnotations;namespace Acme.BookStore.Books
{public class CreateUpdateBookDto{[Required][StringLength(128)]public string Name { get; set; }[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; }}
}
- 这个DTO类被用于在创建或更新书籍的时候从用户界面获取图书信息.
- 它定义了数据注释特性(如
[Required]
)来定义属性的验证规则. DTO由ABP框架自动验证.
就像上面的BookDto
一样,创建一个从CreateUpdateBookDto
对象到Book
实体的映射,最终映射配置类如下:
using Acme.BookStore.Books;
using AutoMapper;namespace Acme.BookStore
{public class BookStoreApplicationAutoMapperProfile : Profile{public BookStoreApplicationAutoMapperProfile(){CreateMap<Book, BookDto>();CreateMap<CreateUpdateBookDto, Book>();}}
}
IBookAppService
下一步是为应用程序定义接口,在Acme.BookStore.Application.Contracts
项目创建 Books
文件夹(命名空间),并在其中添加名为IBookAppService
的接口:
using System;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;namespace Acme.BookStore.Books
{public interface IBookAppService :ICrudAppService< //Defines CRUD methodsBookDto, //Used to show booksGuid, //Primary key of the book entityPagedAndSortedResultRequestDto, //Used for paging/sortingCreateUpdateBookDto> //Used to create/update a book{}
}
- 框架定义应用程序服务的接口不是必需的. 但是,它被建议作为最佳实践.
ICrudAppService
定义了常见的CRUD方法:GetAsync
,GetListAsync
,CreateAsync
,UpdateAsync
和DeleteAsync
. 从这个接口扩展不是必需的,你可以从空的IApplicationService
接口继承并手动定义自己的方法(将在下一部分中完成).ICrudAppService
有一些变体, 你可以在每个方法中使用单独的DTO(例如使用不同的DTO进行创建和更新).
BookAppService
是时候实现IBookAppService
接口了.在Acme.BookStore.Application
项目中创建 Books
文件夹(命名空间),并在其中添加名为 BookAppService
的类:
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, //The Book entityBookDto, //Used to show booksGuid, //Primary key of the book entityPagedAndSortedResultRequestDto, //Used for paging/sortingCreateUpdateBookDto>, //Used to create/update a bookIBookAppService //implement the IBookAppService{public BookAppService(IRepository<Book, Guid> repository): base(repository){}}
}
BookAppService
继承了CrudAppService<...>
.它实现了ICrudAppService
定义的CRUD方法.BookAppService
注入IRepository <Book,Guid>
,这是Book
实体的默认仓储. ABP自动为每个聚合根(或实体)创建默认仓储. 请参阅仓储文档BookAppService
使用IObjectMapper将Book
对象转换为BookDto
对象, 将CreateUpdateBookDto
对象转换为Book
对象. 启动模板使用AutoMapper库作为对象映射提供程序. 我们之前定义了映射, 因此它将按预期工作.
Swagger UI
启动模板配置为使用Swashbuckle.AspNetCore运行swagger UI. 运行应用程序并在浏览器中输入https://localhost:XXXX/swagger/
(用你自己的端口替换XXXX)作为URL. 使用CTRL+F5
运行应用程序 (Acme.BookStore.Web
)并使用浏览器访问https://localhost:<port>/swagger/
on your browser. 使用你自己的端口号替换 <port>
.
你会看到一些内置的服务端点和Book
服务,它们都是REST风格的端点: