Abp VNext 入門——讓ABP跑起來
- 2020 年 12 月 18 日
- 筆記
- ASP.NET MVC, c#, NET Core
因好多群友@我說,ABP他們簡單的了解了下,按照官方的教程一路下來跑不起來(倒在了入門的門口),才有了此文。
此文結合官方文檔,一步一步帶領大家讓ABP跑起來(跨過門口)。
建議大家一步一步實際動手操作下
一、Abp 簡介
ABP是用於創建現代Web應用程式的完整架構和強大的基礎設施! 遵循最佳實踐和約定,為你提供SOLID開發經驗.
ABP 是一個開源應用程式框架,專註於基於ASP.NET Core的Web應用程式開發,但也支援開發其他類型的應用程式.
二、項目創建
作為入門,這裡就不使用CLI創建了,使用在線創建項目,在線地址://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原則和模式去實現分層應用程式模型,該模型由四個基本層組成:
- 表示層: 為用戶提供介面. 使用應用層實現與用戶交互.
- 應用層: 表示層與領域層的中介,編排業務對象執行特定的應用程式任務. 使用應用程式邏輯實現用例.
- 領域層: 包含業務對象以及業務規則. 是應用程式的核心.
- 基礎設施層: 提供通用的技術功能,支援更高的層,主要使用第三方類庫.