ABP框架入門學習(二)——實體層/領域層/應用層實現


上篇文章寫到下載模板,模板的結構簡單介紹、生成數據庫和基礎數據,然后並運行了項目,接下來咋們說說項目的擴展,新建一塊自己的業務,參照現有的項目架構,我們該怎么一步步增加自己的功能?

一、創建Book實體

前面有說道項目領域層是有兩塊組成:

  • TestApp.BookStore.Domain包含你的實體領域服務和其他核心域對象.
  • TestApp.BookStore.Domain.Shared包含可與客戶共享的常量,枚舉或其他域相關對象

TestApp.BookStore.Domain創建一個Books的文件夾,並添加一個Book的基礎類,如下圖:

 

 

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Domain.Entities.Auditing;

namespace TestApp.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; }
    }
}
View Code

 

  • ABP為實體提供了兩個基本的基類: AggregateRootEntityAggregate Root領域驅動設計 概念之一. 可以視為直接查詢和處理的根實體.
  • Book實體繼承了AuditedAggregateRoot,AuditedAggregateRoot類在AggregateRoot類的基礎上添加了一些基礎審計屬性(例如CreationTimeCreatorIdLastModificationTime 等). ABP框架自動為你管理這些屬性.
  • GuidBook實體的主鍵類型.

由於Book實體包含BookType枚舉,所以在TestApp.BookStore.Domain.Shared創建一個Books的文件夾,並添加一個BookType的基礎類,如下圖:

 

 

 

using System;
using System.Collections.Generic;
using System.Text;

namespace TestApp.BookStore.Books
{
    public enum BookType
    {
        Undefined,
        Adventure,
        Biography,
        Dystopia,
        Fantastic,
        Horror,
        Science,
        ScienceFiction,
        Poetry
    }
}
View Code

 

二、將Book實體添加到DbContext中並映射到數據庫表中

EF Core需要你將實體和 DbContext 建立關聯.做法是在TestApp.BookStore.EntityFrameworkCore項目的BookStoreDbContext

 

 

 

添加DbSet屬性.如下所示:

 public DbSet<Book> Books { get; set; }


OnModelCreating方法,為Book實體添加映射代碼:

 builder.Entity<Book>(b =>
        {
            b.ToTable(BookStoreConsts.DbTablePrefix + "Books",BookStoreConsts.DbSchema);
            b.ConfigureByConvention();
            b.Property(x => x.Name).IsRequired().HasMaxLength(128);
        });
  • BookStoreConsts 含有用於表的架構和表前綴的常量值. 使用它不是強制的,但建議在統一的地方控制表前綴.
  • ConfigureByConvention() 方法優雅的配置/映射繼承的屬性,應對所有的實體使用它.

可在數據模型添加初始化數據方便學習ABP Framework功能,如下圖(可忽略)

在 TestApp.BookStore.Domain項目下創建 IDataSeedContributor 的派生類

 

 

 

using System;
using System.Threading.Tasks;
using TestApp.BookStore.Books;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories;

namespace TestApp.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
                );
            }
        }
    }
}
View Code

 

  • 如果數據庫中當前沒有圖書,則此代碼使用 IRepository<Book, Guid>(默認repository)將兩本書插入數據庫.


三、更新數據庫

由於數據表結構和初始化數據調整,所以需要更新下數據庫,將TestApp.BookStore.DbMigrator應用程序設為啟動項目,來更新數據庫,運行完成會發現數據庫book表會多兩條默認數據,如下圖:

 

 

 

  • .DbMigrator 是一個控制台使用程序,可以在開發生產環境遷移數據庫架構初始化種子數據.

四、創建應用程序

前面也說道應用程序跟領域層類似都有兩塊組成:

  • TestApp.BookStore.Application.Contracts 包含你的DTO應用服務接口.
  • TestApp.BookStore.Application 包含你的應用服務實現.

創建一個應用程序服務,使用ABP Framework的 CrudAppService 基類來獲取,創建,更新和刪除書籍.

CrudAppService 基類需要定義實體的基本DTO.

 

在  TestApp.BookStore.Application.Contracts 項目中創建 Books 文件夾(命名空間),添加 BookDto 的DTO類:

using System;
using System.Collections.Generic;
using System.Text;
using Volo.Abp.Application.Dtos;


namespace TestApp.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類被用來在 表示層 和 應用層 傳遞數據.
  • 為了在用戶界面上展示書籍信息,BookDto被用來將書籍數據傳遞到表示層.
  • BookDto繼承自 AuditedEntityDto<Guid>.與上面定義的 Book 實體一樣具有一些審計屬性.

在將書籍返回到表示層時,需要將Book實體轉換為BookDto對象. AutoMapper庫可以在定義了正確的映射時自動執行此轉換. 啟動模板配置了AutoMapper,因此你只需在TestApp.BookStore.Application項目的BookStoreApplicationAutoMapperProfile類中定義映射:

 

 

        CreateMap<Book, BookDto>();

 

TestApp.BookStore.Application.Contracts項目中創建 Books 文件夾(命名空間),並在其中添加名為 CreateUpdateBookDto 的DTO類:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Text;

namespace TestApp.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實體的映射,最終映射配置類如下:

            CreateMap<CreateUpdateBookDto, Book>();

 

TestApp.BookStore.Application.Contracts項目中創建 Books 文件夾(命名空間),並在其中添加名為IBookAppService接口:

using System;
using System.Collections.Generic;
using System.Text;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;

namespace TestApp.BookStore.Books
{
    public interface IBookAppService:
         ICrudAppService< //Defines CRUD methods
            BookDto, //Used to show books
            Guid, //Primary key of the book entity
            PagedAndSortedResultRequestDto, //Used for paging/sorting
            CreateUpdateBookDto> //Used to create/update a book
    {
    }
}
  • 框架定義應用程序服務的接口不是必需的. 但是,它被建議作為最佳實踐.
  • ICrudAppService定義了常見的CRUD方法:GetAsync,GetListAsync,CreateAsync,UpdateAsyncDeleteAsync. 從這個接口擴展不是必需的,你可以從空的IApplicationService接口繼承並手動定義自己的方法(將在下一部分中完成).
  • ICrudAppService有一些變體, 你可以在每個方法中使用單獨的DTO(例如使用不同的DTO進行創建和更新).

TestApp.BookStore.Application.Contracts項目新增文件內容如下圖:

 

在TestApp.BookStore.Application項目中創建 Books 文件夾(命名空間),並在其中添加名為 BookAppService 的類實現IBookAppService接口:

 

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;

namespace TestApp.BookStore.Books
{
    public class BookAppService :
        CrudAppService<
            Book, //The Book entity
            BookDto, //Used to show books
            Guid, //Primary key of the book entity
            PagedAndSortedResultRequestDto, //Used for paging/sorting
            CreateUpdateBookDto>, //Used to create/update a book
        IBookAppService
    {
        public BookAppService(IRepository<Book, Guid> repositoty)
            : base(repositoty)
        {
        }
    }
}

五、自動生成API Controllers

在典型的ASP.NET Core應用程序中,你創建API Controller以將應用程序服務公開為HTTP API端點. 這將允許瀏覽器或第三方客戶端通過HTTP調用它們.

ABP可以自動按照約定將你的應用程序服務配置為MVC API控制器.

六、運行Swagger UI測試API

運行應用程序並在瀏覽器中輸入 https://localhost:XXXX/swagger/(用你自己的端口替換XXXX)作為URL. 使用 CTRL+F5運行應用程序 ( TestApp.BookStore.Web)並使用瀏覽器訪問 https://localhost:<port>/swagger/

 

可以嘗試執行[GET] /api/app/book API來獲取書籍列表, 服務端會返回以下JSON結果:

 

 

到現在為止新增的Book模塊基本完成,下片接着介紹如何操作Book的增刪改查功能......

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM