1. 程式人生 > >ABP vNext模塊系統初試 - 創建留言板模塊

ABP vNext模塊系統初試 - 創建留言板模塊

ack 信息 們的 tab body abp 進行 async log

上次翻譯的ABP vNext介紹發布後,引起了很多ABP好愛者的關註.
那麽就趁熱打鐵,體驗一下新ABP.
新的ABP中我最感興趣的是它的模板系統,所以這次就利用模塊系統做了留言板的例子,分享給大家.

留言板模塊

我們的留言板模塊功能很簡單,就是提供用戶留言的功能(廢話),為了簡單起見,功能都非常簡陋:

  • 通過菜單進入留言板
  • 顯示留言一覽,顯示的項目有:標題,作者和時間
  • 任意用戶可創建留言,修改或刪除自己的留言
  • 管理員可修改或刪除任何留言
  • 留言只有標題和正文,均為純文本(不支持富文本).

使用ABP的模塊系統將以上功能涉及的數據庫,API,UI等打包為一個模塊,以便在以後的項目中復用(這麽簡陋還想復用?

)

註意

  • 讀者最好開發過ABP,對於ABP的基礎知識(如Entity,Repository,Application Service等)有一定的理解
  • 文中的代碼寫法僅為測試和功能驗證,有可能未遵循ABP的最佳實踐,請不要直接用在實際項目中

Ready? Let‘s go to Next!

創建工程

  1. 創建模塊工程

    使用官網提供的模板,註意選擇ASP.NET Core Mvc Module,創建一個模塊工程,命名為WAKU.MessageBoard

    技術分享圖片

  2. 用VS2017打開模塊工程(WAKU.MessageBoard.sln),可以看到模板生成的項目有很多:

    技術分享圖片

    這些工程遵循了官方的最佳實踐,這裏做簡要說明:

    文件夾 工程 說明 用途
    app WAKU.MessageBoard.DemoApp 測試用WEB工程 提供模塊開發階段測試用app
    src WAKU.MessageBoard.Application 應用程序服務工程 定義Service各個實現類
    WAKU.MessageBoard.Application.Contracts 應用程序服務合約工程 定義Service各個接口,DTO
    WAKU.MessageBoard.Domain 域工程 定義Entity
    WAKU.MessageBoard.Domain.Shared 域共享工程 定義所有工程可共用的常量信息等
    WAKU.MessageBoard.EntityFrameworkCore EF Core工程 定義DbContext,提供EF訪問數據庫的基礎設施
    WAKU.MessageBoard.HttpApi HTTP API工程 定義控制器,用來暴露應用程序服務中各個方法
    WAKU.MessageBoard.HttpApi.Client HTTP API客戶端工程 為HTTP API提供客戶端服務
    WAKU.MessageBoard.MongoDB MongoDB工程 定義DbContext,提供MongoDB訪問數據庫的基礎設施(本文中未使用)
    WAKU.MessageBoard.Web WEB工程 定義模塊使用的頁面,視圖,腳本等UI相關的資源
    tests - 各個測試工程 定義針對以上工程的測試用例

準備代碼

  1. 創建Domain

    WAKU.MessageBoard.Domain工程的WAKU\MessageBoard下新建一個命為Messages的文件夾,用來存放留言板的Domain類.

    技術分享圖片

    這個例子中,只有留言一個Domain類,在Messages文件夾下創建該Message類,代碼如下:

    using Volo.Abp.Domain.Entities.Auditing;
    
    namespace WAKU.MessageBoard.Messages
    {
        public class Message : FullAuditedEntity<int>
        {
            /// <summary>
            /// 標題
            /// </summary>
            public string Title { get; set; }
    
            /// <summary>
            /// 正文
            /// </summary>
            public string Content { get; set; }
        }
    }
  2. 增加DbContext屬性

    修改WAKU.MessageBoard.EntityFrameworkCore工程的WAKU\MessageBoard\EntityFrameworkCore下的IMessageBoardDbContextMessageBoardDbContext類,增加Message的DbSet屬性:

     [ConnectionStringName("MessageBoard")]
     public interface IMessageBoardDbContext : IEfCoreDbContext
     {
         DbSet<Message> Messages { get; set; }
     }
    
     [ConnectionStringName("MessageBoard")]
     public class MessageBoardDbContext : AbpDbContext<MessageBoardDbContext>, IMessageBoardDbContext
     {
         ...
    
         public DbSet<Message> Messages { get; set; }
    
         ...
     }
    
  3. 創建Repository

    修改MessageBoardEntityFrameworkCoreModule,使用ABP為各Entity創建默認Repository:

       [DependsOn(
        typeof(MessageBoardDomainModule),
        typeof(AbpEntityFrameworkCoreModule)
    )]
    public class MessageBoardEntityFrameworkCoreModule : AbpModule
    {
        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            context.Services.AddAbpDbContext<MessageBoardDbContext>(options =>
            {
                // 為全部Entity創建默認Repository
                options.AddDefaultRepositories(includeAllEntities: true);
            });
        }
    }
  4. 為Message配置model builder

    修改MessageBoardDbContextModelCreatingExtensions如下:

    public static class MessageBoardDbContextModelCreatingExtensions
    {
        public static void ConfigureMessageBoard(
            this ModelBuilder builder,
            Action<MessageBoardModelBuilderConfigurationOptions> optionsAction = null)
        {
            ...
    
            builder.Entity<Message>(m =>
            {
                m.ToTable(options.TablePrefix + "Messages", options.Schema);
                m.ConfigureFullAudited();
            });
        }
    }
  5. 修改數據庫連接串

    修改WAKU.MessageBoard.DemoApp工程下的appsettings.json.將localhost改為(localdb)\\mssqllocaldb,這樣就可以不用在本地安裝Sql Server,而使用Local Db(安裝VS2017時默認會安裝Local Db)

    {
         "ConnectionStrings": {
             "Default": "Server=(localdb)\\mssqllocaldb;Database=MessageBoardDemoApp;Trusted_Connection=True;MultipleActiveResultSets=true"
         }
     }
  6. 增加數據庫遷移

    右鍵點擊WAKU.MessageBoard.DemoApp,選擇Set as Startup Project,將其設置為啟動工程

    技術分享圖片

    打開Package Manager Console(PMC),將默認工程也設置為app\WAKU.MessageBoard.DemoApp,執行以下命令:

     Add-Migration "AddMessage"

    技術分享圖片

  7. 生成數據庫

    在PMC中執行Update-Database

    技術分享圖片

    生成的數據庫位於%userprofile%文件夾下,名為MessageBoardDemoApp.mdf

    可以通過VS2017的菜單View -> SQL Server Object Explorer查看生成的數據庫,並確認Messages表也正確生成了,表名為MessageBoardMessages:

    技術分享圖片

    為了之後的開發,創建3條測試數據:

    技術分享圖片

  8. 創建Service約定

    1. WAKU.MessageBoard.Application.Contracts工程的WAKU\MessageBoard文件夾下,創建Messages\Dto文件夾,並創建一個名為MessageDto的類:

      public class MessageDto : FullAuditedEntityDto<int>
      {
          /// <summary>
          /// 標題
          /// </summary>
          [Required]
          public string Title { get; set; }
      
          /// <summary>
          /// 正文
          /// </summary>
          [Required]
          public string Content { get; set; }
      }
    2. Messages文件夾下創建IMessageAppService接口:

      public interface IMessageAppService : IAsyncCrudAppService<MessageDto, int>
      {
      
      }

      我們繼承了IAsyncCrudAppService接口,該接口定義了基本的增刪改查(CRUD)方法,已經可以滿足我們的需求了,之後可以根據情況再增加新的方法.

      創建完成的結構如下:

      技術分享圖片

  9. 實現Service

    WAKU.MessageBoard.Application工程的WAKU\MessageBoard文件夾下,創建Messages文件夾,並創建一個名為MessageAppService的類:

    public class MessageAppService : AsyncCrudAppService<Message, MessageDto, int>, IMessageAppService
    {
        public MessageAppService(IRepository<Message, int> repository) : base(repository)
        {
        }
    }

    IMessageAppService接口類似,繼承了AsyncCrudAppService類,使用該類默認實現的增刪改查方法,就不需要再定義額外的方法了.

  10. 創建Controller

    WAKU.MessageBoard.HttpApi工程的WAKU\MessageBoard文件夾下,創建MessageController類,用來暴露Service中的方法:

    [RemoteService]
    [Area("message_board")]
    [Controller]
    [ControllerName("Messages")]
    [Route("api/message_board/messages")]
    [DisableAuditing]
    public class MessageController: AbpController, IMessageAppService
    {
        private readonly IMessageAppService _messageAppService;
    
        public MessageController(IMessageAppService messageAppService)
        {
            _messageAppService = messageAppService;
        }
    
        [HttpGet]
        [Route("{id}")]
        public Task<MessageDto> GetAsync(int id)
        {
            return _messageAppService.GetAsync(id);
        }
    
        [HttpGet]
        [Route("")]
        public Task<PagedResultDto<MessageDto>> GetListAsync(PagedAndSortedResultRequestDto input)
        {
            return _messageAppService.GetListAsync(input);
        }
    
        [HttpPost]
        public Task<MessageDto> CreateAsync(MessageDto input)
        {
            return _messageAppService.CreateAsync(input);
        }
    
        [HttpPost]
        [Route("{id}")]
        public Task<MessageDto> UpdateAsync(int id, MessageDto input)
        {
            return _messageAppService.UpdateAsync(id, input);
        }
    
        [HttpDelete]
        public Task DeleteAsync(int id)
        {
            return _messageAppService.DeleteAsync(id);
        }
    }

    可以看出該類只是Service的一個封裝,定義了API的路由和參數形式,代碼略顯繁瑣.個人希望能像之前版本一樣,由ABP自動生成,估計在將來的版本中會提供.

  11. 啟動DemoApp

    現在我們就已準備好模塊需要的基礎服務了,啟動測試工程WAKU.MessageBoard.DemoApp,一切正常的話就看到啟動頁面:

    技術分享圖片

  12. 用Swagger測試API

    在瀏覽器的地址欄中增加/swagger,會進入Swagger的頁面:

    技術分享圖片

    可以看到Controller中定義的各個方法已經顯示出來,我們可以測試一下基本的增刪改查功能是否正常,這裏測試一下get方法,看看之前的測試數據能否取出:

    技術分享圖片

    這裏我們通過URL取得id為2的留言,可以看到數據能正常取出.

小結

總結一下我們到現在為止的工作:

  • 創建了Message的Domain
  • 增加EF Core相關的設置
  • 生成了數據庫
  • 創建了Service,定義了CRUD方法
  • 創建了API Controller,暴露了Service方法
  • 測試了API

到現在為止,我們已經為留言模板實現了~健壯的~基礎服務,下一篇我們將使用這些基礎服務,做一些稍微實用的功能: 為留言板創建UI,讓用戶真正的能使用留言功能.

如果你喜歡本文,請點擊"推薦",更歡迎留言進行討論,你的支持是我的最大動力!

ABP vNext模塊系統初試 - 創建留言板模塊