基于abp vnext手动编写一个功能的完整步骤

        本文忽略对abp vnext框架及DDD软件开发方法的解析,直入主题,讲解一个功能实现中各层代码的实现,步骤如下:

        1、下载模块框架代码

        通过使用 abp cli或者直接通过官方进行下载,如下图:

基于abp vnext手动编写一个功能的完整步骤_第1张图片

2、领域层定义

领域层划分为两个项目:

  • Domain.Shared 包(项目) 命名为CompanyName.ModuleName.Domain.Shared,包含常量,枚举和其他类型, 它不能包含实体,存储库,域服务或任何其他业务对象. 可以安全地与模块中的所有层使用. 此包也可以与第三方客户端使用.
  • Domain 包(项目) 命名为CompanyName.ModuleName.Domain, 包含实体, 仓储接口,领域服务接口及其实现和其他领域对象.
    • Domain 包依赖于 Domain.Shared 包.

1)实体定义

基于abp vnext手动编写一个功能的完整步骤_第2张图片

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Text;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;

namespace demo1.Articles
{
    /// 
    /// 文章
    /// 
    public class Article : CreationAuditedEntity, IMultiTenant
    {
        /// 
        /// 租户Id
        /// 
        public Guid? TenantId { get; private set; }

        /// 
        /// 标题
        /// 
        /// 
        [Required]
        [MaxLength(100)]
        public string Title { get; set; }

        /// 
        /// 副标题
        /// 
        /// 
        [MaxLength(100)]
        public string SubTitle { get; set; }

        /// 
        /// 作者
        /// 
        /// 
        [MaxLength(50)]
        public string Aauthor { get; set; }

        /// 
        /// 内容
        /// 
        /// 
        [Required]
        public string Content { get; set; }

        /// 
        /// 来源
        /// 
        public string Source { get; set; }

    }
}

2)仓储接口

一般存放在与实体定义在同一个文件夹下,命名约定为:I{实体名}Repositor,如:IArticleRepository。

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using Volo.Abp.Domain.Repositories;

namespace demo1.Articles
{
    /// 
    /// 文章 仓储接口
    /// 
    public interface IArticleRepository : IRepository
    {
        Task> GetListAsync(
           bool paged = true,
           string sorting = null,
           int maxResultCount = int.MaxValue,
           int skipCount = 0,
           string filter = null,
           CancellationToken cancellationToken = default
       );

        Task GetCountAsync(
            string filter = null,
            CancellationToken cancellationToken = default);
    }
}

 3、基础设施层的代码变动

  • 推荐 为每个orm/数据库集成创建一个独立的集成包, 比如Entity Framework Core 和 MongoDB.
    • 推荐 例如, 创建一个抽象Entity Framework Core集成的CompanyName.ModuleName.EntityFrameworkCore 包. ORM 集成包依赖于 Domain 包.
    • 不推荐 依赖于orm/数据库集成包中的其他层.
  • 推荐 为每个主要的库创建一个独立的集成包, 在不影响其他包的情况下可以被另一个库替换.

基于abp vnext手动编写一个功能的完整步骤_第3张图片

 基于abp vnext手动编写一个功能的完整步骤_第4张图片

基于abp vnext手动编写一个功能的完整步骤_第5张图片 基于abp vnext手动编写一个功能的完整步骤_第6张图片

基于abp vnext手动编写一个功能的完整步骤_第7张图片

using demo1.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;

namespace demo1.Articles
{
    public class ArticleRepository : EfCoreRepository, IArticleRepository
    {
        public ArticleRepository(IDbContextProvider dbContextProvider) : base(dbContextProvider)
        {
        }

        public virtual async Task> GetListAsync(
            bool paged = true,
            string sorting = null,
            int maxResultCount = int.MaxValue,
            int skipCount = 0,
            string filter = null,
            CancellationToken cancellationToken = default
        )
        {
            var query = (await GetDbSetAsync())
                .WhereIf(
                    !filter.IsNullOrWhiteSpace(),
                    u => u.Title.Contains(filter)
                    )
                .OrderBy(sorting.IsNullOrWhiteSpace() ? "CreationTime desc" : sorting);

            if (paged)
            {
                return await query.PageBy(skipCount, maxResultCount).ToListAsync(GetCancellationToken(cancellationToken));
            }
            else
            {
                return await query.ToListAsync(GetCancellationToken(cancellationToken));
            }
        }

        public virtual async Task GetCountAsync(
            string filter = null,
            CancellationToken cancellationToken = default)
        {
            return await (await GetDbSetAsync())
                .WhereIf(
                    !filter.IsNullOrWhiteSpace(),
                    u => u.Title.Contains(filter)
                    )
                .LongCountAsync(GetCancellationToken(cancellationToken));
        }
    }
}

4、应用服务层的代码变动

将应用服务层划分为两个项目:

  • Application.Contracts 包(项目) 命名为*CompanyName.ModuleName.Application.Contracts,包含应用服务接口和相关的数据传输对象(DTO).
    • Application contract 包依赖于 Domain.Shared 包.
  • Application 包(项目)命名为CompanyName.ModuleName.Application,包含应用服务实现.
    • Application 包依赖于 Domain 包和 Application.Contracts 包.

基于abp vnext手动编写一个功能的完整步骤_第8张图片 基于abp vnext手动编写一个功能的完整步骤_第9张图片

 基于abp vnext手动编写一个功能的完整步骤_第10张图片

5、数据库迁移 

使用add-migration 和Update-Database进行数据库迁移。

总结:每个领域功能的开发流程大致如此。

 

你可能感兴趣的:(后端开发技术,c#,开发语言)