ABP vNext模塊系統初試 - 創建留言板模塊
上次翻譯的ABP vNext介紹發布後,引起了很多ABP好愛者的關註.
那麽就趁熱打鐵,體驗一下新ABP.
新的ABP中我最感興趣的是它的模板系統,所以這次就利用模塊系統做了留言板的例子,分享給大家.
留言板模塊
我們的留言板模塊功能很簡單,就是提供用戶留言的功能(廢話),為了簡單起見,功能都非常簡陋:
- 通過菜單進入留言板
- 顯示留言一覽,顯示的項目有:標題,作者和時間
- 任意用戶可創建留言,修改或刪除自己的留言
- 管理員可修改或刪除任何留言
- 留言只有標題和正文,均為純文本(不支持富文本).
使用ABP的模塊系統將以上功能涉及的數據庫,API,UI等打包為一個模塊,以便在以後的項目中復用(這麽簡陋還想復用?
註意
- 讀者最好開發過ABP,對於ABP的基礎知識(如Entity,Repository,Application Service等)有一定的理解
- 文中的代碼寫法僅為測試和功能驗證,有可能未遵循ABP的最佳實踐,請不要直接用在實際項目中
Ready? Let‘s go to Next!
創建工程
創建模塊工程
使用官網提供的模板,註意選擇
ASP.NET Core Mvc Module
,創建一個模塊工程,命名為WAKU.MessageBoard
:用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 - 各個測試工程 定義針對以上工程的測試用例
準備代碼
創建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; } } }
增加DbContext屬性
修改
WAKU.MessageBoard.EntityFrameworkCore
工程的WAKU\MessageBoard\EntityFrameworkCore
下的IMessageBoardDbContext
和MessageBoardDbContext
類,增加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; } ... }
創建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); }); } }
為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(); }); } }
修改數據庫連接串
修改
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" } }
增加數據庫遷移
右鍵點擊
WAKU.MessageBoard.DemoApp
,選擇Set as Startup Project
,將其設置為啟動工程打開
Package Manager Console
(PMC),將默認工程也設置為app\WAKU.MessageBoard.DemoApp
,執行以下命令:Add-Migration "AddMessage"
生成數據庫
在PMC中執行
Update-Database
生成的數據庫位於
%userprofile%
文件夾下,名為MessageBoardDemoApp.mdf
可以通過VS2017的菜單
View
->SQL Server Object Explorer
查看生成的數據庫,並確認Messages表也正確生成了,表名為MessageBoardMessages
:為了之後的開發,創建3條測試數據:
創建Service約定
在
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; } }
在
Messages
文件夾下創建IMessageAppService
接口:public interface IMessageAppService : IAsyncCrudAppService<MessageDto, int> { }
我們繼承了
IAsyncCrudAppService
接口,該接口定義了基本的增刪改查(CRUD)方法,已經可以滿足我們的需求了,之後可以根據情況再增加新的方法.創建完成的結構如下:
實現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
類,使用該類默認實現的增刪改查方法,就不需要再定義額外的方法了.創建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自動生成,估計在將來的版本中會提供.
啟動DemoApp
現在我們就已準備好模塊需要的基礎服務了,啟動測試工程
WAKU.MessageBoard.DemoApp
,一切正常的話就看到啟動頁面:用Swagger測試API
在瀏覽器的地址欄中增加
/swagger
,會進入Swagger的頁面:可以看到Controller中定義的各個方法已經顯示出來,我們可以測試一下基本的增刪改查功能是否正常,這裏測試一下get方法,看看之前的測試數據能否取出:
這裏我們通過URL取得id為2的留言,可以看到數據能正常取出.
小結
總結一下我們到現在為止的工作:
- 創建了Message的Domain
- 增加EF Core相關的設置
- 生成了數據庫
- 創建了Service,定義了CRUD方法
- 創建了API Controller,暴露了Service方法
- 測試了API
到現在為止,我們已經為留言模板實現了~健壯的~基礎服務,下一篇我們將使用這些基礎服務,做一些稍微實用的功能: 為留言板創建UI,讓用戶真正的能使用留言功能.
如果你喜歡本文,請點擊"推薦",更歡迎留言進行討論,你的支持是我的最大動力!
ABP vNext模塊系統初試 - 創建留言板模塊