[Abp vNext microservice practice] - Business Development

Keywords: Vue Database SQL

In the previous several articles, we introduced abp vNext microservice framework, development environment construction and access to the front-end framework of vue element admin respectively. After the basic functions of user role management are implemented in vue element admin, we can start business development. This article will introduce how to develop business interface and front-end page implementation in abp vNext in detail.

Business interface development

The business interface is aimed at the business api interface. After the business interface is implemented and published in the abp vNext microservice, the front-end obtains the interface and develops the interface. Thus, the front-end and back-end of the abp vNext microservice are developed separately.

step1: create entity (model)

The business development of abp vNext microservice framework also adopts the classic ddd architecture style and ef core code first mode, so all business starts from the domain model. Create a data dictionary model as follows:

public class DataDictionary : AuditedAggregateRoot<Guid>,ISoftDelete
    {
        [NotNull]
        public string Name { get; set; }

        public string Code { get; set; }

        [NotNull]
        public string FullName { get; set; }

        public Guid? CategoryID { get; set; }

        public string Notes { get; set; }

        public Guid? PID { get; set; }


[NotNull] public int SEQ { get; set; } public bool IsEdit { get; set; } public bool IsDeleted { get; set; } }

step2: add AbpDbContext:

public DbSet<DataDictionary> Dictionary { get; set; }

step3: build ef entity:

builder.Entity<DataDictionary>(b =>
            {
                b.ToTable("Dictionary");

                b.ConfigureConcurrencyStamp();
                b.ConfigureExtraProperties();
                b.ConfigureAudited();

                b.Property(x => x.Name).IsRequired().HasMaxLength(ProductConsts.MaxNameLength);
                b.Property(x => x.Code).HasMaxLength(ProductConsts.MaxCodeLength);
                b.Property(x => x.FullName).IsRequired().HasMaxLength(ProductConsts.MaxFullNameLength);
                b.Property(x => x.Notes).HasMaxLength(ProductConsts.MaxNotesLength);
                b.Property(x => x.SEQ).IsRequired();

                b.HasIndex(q => q.Code);
                b.HasIndex(q => q.Name);
                b.HasIndex(q => q.CategoryID);
            });

step4: use ef to migrate the database:

Add-Migration
 Update-Database

Check whether the output log was migrated successfully.

Create data dictionary application service interface

Step 5: create data dictionary interface and dto as follows:

 

public interface IDictionaryAppService : IApplicationService
    {
        Task<PagedResultDto<DictionaryDto>> GetAll(GetDictionaryInputDto input);

        Task<DictionaryDto> Get(Guid id);

        Task<DictionaryDto> Create(CreateDictionaryDto input);

        Task<DictionaryDto> Update(Guid id, UpdateDictionary input);

        Task Delete(List<Guid> ids);
    }
public class CreateDictionaryDto
    {
        [Required]
        [StringLength(ProductConsts.MaxNameLength)]
        public string Name { get; set; }

        [StringLength(ProductConsts.MaxCodeLength)]
        public string Code { get; set; }

        public Guid? CategoryID { get; set; }

        [StringLength(ProductConsts.MaxNotesLength)]
        public string Notes { get; set; }

        public Guid? PID { get; set; }

        public int SEQ { get; set; }

        public bool IsEdit { get; set; }
    }
public class DictionaryDto : AuditedEntityDto<Guid>
    {
        public string Name { get; set; }

        public string Code { get; set; }

        public string FullName { get; set; }

        public Guid? CategoryID { get; set; }

        public string Notes { get; set; }

        public Guid? PID { get; set; }

        public int SEQ { get; set; }

        public bool IsEdit { get; set; }
    }
public class GetDictionaryInputDto: PagedAndSortedResultRequestDto
    {
        public string Filter { get; set; }

        public Guid CategoryID { get; set; }
    }
public class UpdateDictionary
    {
        [StringLength(ProductConsts.MaxNotesLength)]
        public string Notes { get; set; }

        public Guid? PID { get; set; }

        public int SEQ { get; set; }
    }

Implementation of data dictionary application service

step6: the application layer is implemented as follows:

Inherit base class:

public class DictionaryAppService : ApplicationService, IDictionaryAppService

Injection storage:

private readonly IRepository<DataDictionary, Guid> _repository;


     public DictionaryAppService( IRepository<DataDictionary, Guid> repository) { _repository = repository; }

Implementation interface

newly added:

public async Task<DictionaryDto> Create(CreateDictionaryDto input)
        {
            var existingDic = await _repository.FirstOrDefaultAsync(d => d.Name == input.Name);
            if (existingDic != null)
            {
                throw new BusinessException("name: "+input.Name+"Already exists");
            }var result = await _repository.InsertAsync(new DataDictionary
            {
                Id = GuidGenerator.Create(),
                Name = input.Name,
                Code = input.Code,
                FullName = input.Name,
                CategoryID = input.CategoryID,
                Notes = input.Notes,
                PID = input.PID,
                SEQ = input.SEQ,
                IsEdit=input.IsEdit
            });

            return ObjectMapper.Map<DataDictionary, DictionaryDto>(result);
        }

Delete:

public async Task Delete(List<Guid> ids)
        {
            foreach (var id in ids)
            {
                await _repository.DeleteAsync(id);
            }
        }

Query:

public async Task<DictionaryDto> Get(Guid id)
        {
            var query = await _repository.GetAsync(id);
            var dto = ObjectMapper.Map<DataDictionary, DictionaryDto>(query);return dto;
        }

        public async Task<PagedResultDto<DictionaryDto>> GetAll(GetDictionaryInputDto input)
        {
            var query = _repository
                .Where(d => d.CategoryID == input.CategoryID)
                .WhereIf(!string.IsNullOrEmpty(input.Filter), d => d.Name.Contains(input.Filter) ||
                                                                   d.Code.Contains(input.Filter));

            var items = await query.OrderBy(input.Sorting ?? "SEQ")
                                        .Skip(input.SkipCount)
                                        .Take(input.MaxResultCount).ToListAsync();

            var totalCount = await query.CountAsync();
var dtos = ObjectMapper.Map<List<DataDictionary>, List<DictionaryDto>>(items);return new PagedResultDto<DictionaryDto>(totalCount, dtos);
        }

Modification:

public async Task<DictionaryDto> Update(Guid id, UpdateDictionary input)
        {var dic = await _repository.GetAsync(id);
            dic.Notes = input.Notes;
            dic.SEQ = input.SEQ;

            return ObjectMapper.Map<DataDictionary, DictionaryDto>(dic);
        }

Add data dictionary permission

step7: permissions

Add the static class DataDictionary in ProductManagementPermissions:

public static class DataDictionary
        {
            public const string Default = BasicDataManagement + ".DataDictionary";
            public const string Delete = Default + ".Delete";
            public const string Update = Default + ".Update";
            public const string Create = Default + ".Create";
        }

step8: construct permissions

Add dataDictionary to product managementpermissiondefinitionprovider:

var dataDictionary = basicDataManagementGroup.AddPermission(ProductManagementPermissions.DataDictionary.Default, L("DataDictionary"));
            dataDictionary.AddChild(ProductManagementPermissions.DataDictionary.Create, L("Permission:Create"));
            dataDictionary.AddChild(ProductManagementPermissions.DataDictionary.Delete, L("Permission:Delete"));
            dataDictionary.AddChild(ProductManagementPermissions.DataDictionary.Update, L("Permission:Edit"));

Add permission filters to the data dictionary application service after adding

[Authorize(ProductManagementPermissions.DataDictionary.Default)]
[Authorize(ProductManagementPermissions.DataDictionary.Create)]
[Authorize(ProductManagementPermissions.DataDictionary.Delete)]
[Authorize(ProductManagementPermissions.DataDictionary.Update)]

Data dictionary DTO mapping

step9: add data dictionary model to product management application automapperprofile - Dto mapping:

CreateMap<DataDictionary, DictionaryDto>();

Data Dictionary web api implementation

Step 10: the original application service dynamic api is not used in abp vNext. Now the api needs to be implemented in the controller

    [RemoteService]
    [Area("basicData")]
    [Route("api/basicData/dataDictionary")]
    public class DataDictionaryController : AbpController, IDictionaryAppService
    {
        private readonly IDictionaryAppService _dictionaryAppService;

        public DataDictionaryController(IDictionaryAppService dictionaryAppService)
        {
            _dictionaryAppService = dictionaryAppService;
        }

        [HttpPost]
        public Task<DictionaryDto> Create(CreateDictionaryDto input)
        {
            return _dictionaryAppService.Create(input);
        }

        [HttpPost]
        [Route("Delete")]
        public Task Delete(List<Guid> ids)
        {
            return _dictionaryAppService.Delete(ids);
        }

        [HttpGet]
        [Route("{id}")]
        public Task<DictionaryDto> Get(Guid id)
        {
            return _dictionaryAppService.Get(id);
        }

        [HttpGet]
        [Route("all")]
        public Task<PagedResultDto<DictionaryDto>> GetAll(GetDictionaryInputDto input)
        {
            return _dictionaryAppService.GetAll(input);
        }

        [HttpPut]
        [Route("{id}")]
        public Task<DictionaryDto> Update(Guid id, UpdateDictionary input)
        {
            return _dictionaryAppService.Update(id, input);
        }
    }

swagger document

summary

The business development mode of abp vNext has not changed much. Although the process of interface development is a little tedious, it is very necessary for business splitting and model decoupling. The architecture style of ddd allows developers to query easily and efficiently without relying on sql syntax, which is very lucky for code maintenance and project handover. In addition, abp vNext perfectly encapsulates identity, permission, model validation, exception handling, etc., which enables developers to focus on business development.

Article directory: https://www.cnblogs.com/william-xu/p/12047529.html

Posted by lou28 on Fri, 12 Jun 2020 03:15:14 -0700