ABP vNext模块系统初试 - 创建留言板模块

Posted waku

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ABP vNext模块系统初试 - 创建留言板模块相关的知识,希望对你有一定的参考价值。

上次翻译的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工程的WAKUMessageBoard下新建一个命为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工程的WAKUMessageBoardEntityFrameworkCore下的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),将默认工程也设置为appWAKU.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工程的WAKUMessageBoard文件夹下,创建MessagesDto文件夹,并创建一个名为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工程的WAKUMessageBoard文件夹下,创建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工程的WAKUMessageBoard文件夹下,创建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模块系统初试 - 创建留言板模块的主要内容,如果未能解决你的问题,请参考以下文章

ABP vNext微服务架构详细教程——基础服务层

Abp.Io(vNext)开发体会

Abp.Io(vNext)开发体会

.NET 6 之 ABP vNext 初体验

ABP vNext

F_01 采用Abp vnext构建Ngala.Iot平台的基础服务