因好多群友@我說,ABP他們簡單的了解了下,按照官方的教程一路下來跑不起來(倒在了入門的門口),才有了此文。
此文結合官方文檔,一步一步帶領大家讓ABP跑起來(跨過門口)。
建議大家一步一步實際動手操作下
一、Abp 簡介
ABP是用於創建現代Web應用程序的完整架構和強大的基礎設施! 遵循最佳實踐和約定,為你提供SOLID開發經驗.
ABP 是一個開源應用程序框架,專注於基於ASP.NET Core的Web應用程序開發,但也支持開發其他類型的應用程序.
二、項目創建
作為入門,這里就不使用CLI創建了,使用在線創建項目,在線地址:https://abp.io/get-started,為了演示,項目名稱就用官方的Acme.BookStore

下載完解壓后,使用VS2019 打開后

下面我將帶領大家搭建一個簡單的CURD,並簡單的帶大家認識它的分層及各層是干啥的。
三、開發教程
3.1、在 Acme.BookStore.Domain.Share 層下創建 BookType 枚舉
public enum BookType { Undefined, Adventure, Biography, Dystopia, Fantastic, Horror, Science, ScienceFiction, Poetry }
3.2、在 Acme.BookStore.Domain 層下創建Book實體
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; } }
3.3、在 Acme.BookStore.EntityFrameworkCore 層下的 BookStoreDbContext 類中將 Book 實體加入
[ConnectionStringName("Default")] public class BookStoreDbContext : AbpDbContext<BookStoreDbContext> { public DbSet<AppUser> Users { get; set; } public DbSet<Book> Books { get; set; } }
3.4、將 Book 實體映射到數據庫表中
在 Acme.BookStore.EntityFrameworkCore 層下的 BookStoreDbContextModelCreatingExtensions 類中的 ConfigureBookStore 方法中添加 Book 實體的映射文件
public static class BookStoreDbContextModelCreatingExtensions { public static void ConfigureBookStore(this ModelBuilder builder) { Check.NotNull(builder, nameof(builder)); builder.Entity<Book>(b => { b.ToTable(BookStoreConsts.DbTablePrefix + "Books", BookStoreConsts.DbSchema); b.ConfigureByConvention(); b.Property(x => x.Name).IsRequired().HasMaxLength(128); }); } }
3.5、數據遷移
- 打開 程序包管理器控制台(PMC)

- 選擇 Acme.BookStore.EntityFrameworkCore.DbMigrations 作為默認項目並使用 Add-Migraction 命令遷移項目 成功后會創建一個遷移類


3.6、添加種子數據(可選)
在 Acme.BookStore.Domain 層下創建 BookStoreDataSeederContributor 類
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 ); } } }
3.7、更新數據庫
將 Acme.BookStore.DbMigrator 設為啟動項目,並更改它下面的 appsettings.json 文件
更改 appsettings.json 文件中的數據庫連接字符串(這里我使用VS自帶的SqlServer數據庫)。
3.7.1、視圖 —> SQL Server對象資源管理器

3.7.2、創建數據庫 BootStore


3.7.3、獲取連接字符串


3.7.4、更改 appsettings.json ,將上一步復制的數據庫連接字符串替換到 ConnectionString->Default 的 值中

3.7.5、F5運行項目

3.8、在 Acme.BookStore.Application.Contracts 層下創建 BookDto 類及CreateUpdateBookDto類型,並使用 AutoMapper 將 Book 實體轉成 BookDto 對象,將CreateUpdateBookDto對象轉成Book實體的映射
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; } } 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; } }
在 Acme.BookStore.Application 層下的 BookStoreApplicationAutoMapperProfile 類中將 Book 實體轉成 BookDto 對象
namespace Acme.BookStore { public class BookStoreApplicationAutoMapperProfile : Profile { public BookStoreApplicationAutoMapperProfile() { /* You can configure your AutoMapper mapping configuration here. * Alternatively, you can split your mapping configurations * into multiple profile classes for a better organization. */ CreateMap<Book, BookDto>(); CreateMap<CreateUpdateBookDto, Book>(); } } }
3.9、創建 IBookAppService 接口 及它的實現類 BookAppService
在 Acme.BookStore.Application.Contracts 項目下 添加 IBookAppService 接口
namespace Acme.BookStore { public interface IBookAppService : ICrudAppService<//定義CRUD方法 BookDto,//用來展示 Guid,//主鍵類型 PagedAndSortedResultRequestDto,//用於分頁和排序 CreateUpdateBookDto,//用於創建 CreateUpdateBookDto//用於更新 > { } }
在 Acme.BookStore.Application 項目下添加 BookAppService 類
namespace Acme.BookStore
{
public class BookAppService : CrudAppService< Book, BookDto, Guid, PagedAndSortedResultRequestDto, CreateUpdateBookDto, CreateUpdateBookDto>, IBookAppService { public BookAppService(IRepository<Book, Guid> repository) : base(repository) { } } }
3.10、設置 Acme.BookStore.HttpApi.Host 為啟動項目,並修改它的 appsettings.json 文件並運行
3.10.1、設置 appsettings.json 設置方式同 3.7.4
3.10.2 運行項目

是不是非常奇怪,通常我們需要創建Controller以將應用程序服務公開為HTTP API端點。而ABP可以自動按照約定(慣例)將應用程序服務配置為MVC API控制器並使用 Swagger 來管理API文檔。是不是很酷,我們沒有編寫任何代碼來創建API控制器,但是現在我們有了一個可以正常使用的REST API!
四、ABP分層

4.1、Domain
Domain(領域) 划分為兩個項目,Domain.Share 和 Domain
Domain.Share :包含常量,枚舉和其他類型, 它不能包含實體,存儲庫,域服務或任何其他業務對象. 可以安全地與模塊中的所有層使用. 此包也可以與第三方客戶端使用.
Domain: 包含實體, 倉儲接口,領域服務接口及其實現和其他領域對象. Domain 包依賴於 Domain.Shared 包.
4.2、Application
Application(應用服務) 划分為兩個項目 Application.Contracts 和 Application
Application.Contracts:包含應用服務接口和相關的數據傳輸對象(DTO). Application contract 包依賴於 Domain.Shared 包
Application:包含應用服務實現. Application 包依賴於 Domain 包和 Application.Contracts 包
4.3、Infrastructure
Infrastructure(基礎設施) 為每個orm/數據庫集成創建一個獨立的集成包, 比如Entity Framework Core 和 MongoDB.
4.4、HTTP
- 為模塊開發REST風格的HTTP API,
- 為每個應用服務創建一個Controller (通常通過實現其接口). 這些控制器使用應用服務接口來委托操作. 它根據需要配置路由, HTTP方法和其他與Web相關的東西.
- HTTP API 包只依賴於 Application.Contracts 包. 不要依賴 Application 包,
- 創建一個為HTTP API包提供客戶端服務的HTTP API Client包,這些客戶端服務將應用服務接口實現遠程端點的客戶端.HTTP API Client 包僅依賴於 Application.Contracts 包 使用ABP框架提供的動態代理HTTP C#客戶端的功能.
4.5、Web
包含頁面,視圖,腳本,樣式,圖像和其他UI組件,Web 包僅依賴於 HttpApi 包
ABP框架遵循DDD原則和模式去實現分層應用程序模型,該模型由四個基本層組成:
- 表示層: 為用戶提供接口. 使用應用層實現與用戶交互.
- 應用層: 表示層與領域層的中介,編排業務對象執行特定的應用程序任務. 使用應用程序邏輯實現用例.
- 領域層: 包含業務對象以及業務規則. 是應用程序的核心.
- 基礎設施層: 提供通用的技術功能,支持更高的層,主要使用第三方類庫.