[Abp vNext微服务实践] - 业务开发
前几篇分别介绍了abp vNext微服务框架、开发环境搭建和vue element admin前端框架接入,在vue element admin中实现用户角色管理基本功能后就可以开始进行业务开发了,本篇会详细的介绍如何在abp vNext中开发业务接口和前端页面实现。
业务接口开发
业务接口就是针对业务api接口,通过abp vNext微服务中实现并发布业务接口后,前端获取接口并进行界面开发,如此就实现了abp vNext微服务的前后端分离开发。
step1:创建实体(model)
abp vNext微服务框架中的业务开发同样采用了经典的ddd架构风格和ef core 的code first模式,所以一切的业务都从领域模型(domain)开始。创建数据字典模型如下:
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:加入AbpDbContext:
public DbSet<DataDictionary> Dictionary { get; set; }
step3:构建ef实体:
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:使用ef迁移数据库:
Add-Migration
Update-Database
查看输出日志是否成功迁移。
创建数据字典应用服务接口
step5:创建数据字典接口和dto如下:
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; }
}
实现数据字典应用服务
step6:应用层实现如下:
继承基类:
public class DictionaryAppService : ApplicationService, IDictionaryAppService
注入仓储:
private readonly IRepository<DataDictionary, Guid> _repository; public DictionaryAppService(
IRepository<DataDictionary, Guid> repository)
{
_repository = repository;
}
实现接口
新增:
public async Task<DictionaryDto> Create(CreateDictionaryDto input)
{
var existingDic = await _repository.FirstOrDefaultAsync(d => d.Name == input.Name);
if (existingDic != null)
{
throw new BusinessException("名称: "+input.Name+"已存在");
}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);
}
删除:
public async Task Delete(List<Guid> ids)
{
foreach (var id in ids)
{
await _repository.DeleteAsync(id);
}
}
查询:
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);
}
修改:
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);
}
增加数据字典权限
step7:权限
ProductManagementPermissions中增加静态类DataDictionary:
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:构造权限
ProductManagementPermissionDefinitionProvider中增加dataDictionary:
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"));
增加完成后在数据字典应用服务中分别加上权限过滤器
[Authorize(ProductManagementPermissions.DataDictionary.Default)]
[Authorize(ProductManagementPermissions.DataDictionary.Create)]
[Authorize(ProductManagementPermissions.DataDictionary.Delete)]
[Authorize(ProductManagementPermissions.DataDictionary.Update)]
数据字典DTO映射
step9:ProductManagementApplicationAutoMapperProfile中增加数据字典模型-Dto映射:
CreateMap<DataDictionary, DictionaryDto>();
数据字典web api实现
step10:abp vNext中没有使用原先的应用服务动态api,现在api需要在控制器中实现
[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文档
总结
abp vNext的业务开发模式并没有做太多改动,虽然接口开发的过程有些繁琐,但是对于业务拆分和模型解耦来说是非常有必要的。ddd的架构风格让开发人员无需依赖于sql语法,可以使用抽象的仓储进行轻松高效的查询,这对于代码维护和项目交接来说是十分幸运的。此外,abp vNext还将身份、权限、模型验证、异常处理等进行了完美封装,使得开发人员可以专注于业务开发。
文章目录:https://www.cnblogs.com/william-xu/p/12047529.html
[Abp vNext微服务实践] - 业务开发的更多相关文章
- [Abp vNext微服务实践] - 文章目录
简介 ABP vNext是volosoft的新一代框架,ABP(vNext)完全使用.NET CORE和DDD(领域驱动)打造,目前GitHub已有6K+次提交,发布版本超过40次,Nuget包下载量 ...
- [Abp vNext微服务实践] - 前后端分类
一.前景 abp vNext是ABP 开源 Web应用程序框架,是abp的新一代开源web框架.框架完美的集成.net core.identity server4等开源框架,适用于构建web应用程序和 ...
- [Abp vNext微服务实践] - 框架分析
一.简介 abp vNext新框架的热度一直都很高,于是最近上手将vNext的微服务Demo做了一番研究.我的体验是,vNext的微服务架构确实比较成熟,但是十分难以上手,对于没有微服务开发经验的.n ...
- [Abp vNext微服务实践] - 添加中文语言
简介 abp vNext中提供了多语言功能,默认语言是英文,没有提供中文语言包.在业务开发中,定义权限后需要用中文的备注提供角色选择,本篇将介绍如何在abp vNext中加入中文语言. step1:添 ...
- [Abp vNext微服务实践] - 服务通讯
简介 服务通讯是微服务架构中必不可少的功能,服务通讯的效率决定了微服务架构的优略.常用的微服务通讯策略有两种,分别是rpc.http,其中rpc以gRpc框架为代表使用者最多.abp vNext微服务 ...
- [Abp vNext微服务实践] - vue-element-admin管理Identity
一.简介 abp vNext微服务框架中已经提供通用权限和用户角色管理模块,管理UI使用的是MVC模式,不适用于国内主打的MVVM开发模式.在前端框架选型后笔者决定改造abp vNext微服务框架中原 ...
- [Abp vNext微服务实践] - 启动流程
前几篇分别介绍了abp vNext微服务框架和微服务CI/CD环境搭建,本篇开始介绍vNext微服务框架的开发环境搭建. 环境准备 官方介绍的系统架构图如下: 上图中身份服务和网关服务已经集成在系统中 ...
- [Abp vNext微服务实践] - 租户登录
简介 Abp vNext微服务授权验证基于ids4,实现租户登录需要在授权服务中获取token,和之前的介绍的登录方式一样,只是多了tenant参数.本篇将介绍在Abp vNext授权服务中启用多租户 ...
- [Abp vNext微服务实践] - vue-element-admin登录二
简介: Vue Element Admin是基于vue.element ui开发的后台管理ui,abp vNext是abp新一代微服务框架.本篇将会介绍如何改造Vue Element Admin权限验 ...
随机推荐
- MySQL简单管理
基础入门 ============管理MySQL========== .查看MySQL版本 mysqladmin --version .启动MySQL /etc/init.d/mysqld start ...
- unity读取灰度图生成等值线图
准备灰度图 grayTest.png,放置于Assets下StreamingAssets文件夹中. 在场景中添加RawImage用于显示最后的等值线图. 生成等值线的过程,使用Marching ...
- git clone、 remote、fetch、pull、push、remote
git clone命令笔记 作用:远程克隆版本库 1. 克隆版本库 git clone <版本库的网址> git clone zoran@192.168.2.167:/data/gitda ...
- 在Ubuntu上安装Intellij IDEA并创建桌面快捷方式
环境信息 版本号 Ubuntu 18.04 LTS Intellij IDEA 2019.1.3 1.首先从官网获取安装包 官方下载地址传送门 然后我就在下载目录下得到了tar.gz的包 2.接下来开 ...
- selenium3关于ddt驱动之读取json文件。。。
from selenium import webdriver import ddt import time import unittest """ DDT(驱动.json ...
- 【DSP开发】CMD文件
DSP的存储器的地址范围,CMD是主要是根据那个来编的. CMD 它是用来分配rom和ram空间用的,告诉链接程序怎样计算地址和分配空间. 所以不同的芯片就有不同大小的rom和ram.放用户程序的地方 ...
- SpringBoot异步编程
异步调用:当我们执行一个方法时,假如这个方法中有多个耗时的任务需要同时去做,而且又不着急等待这个结果时可以让客户端立即返回然后,后台慢慢去计算任务.当然你也可以选择等这些任务都执行完了,再返回给客户端 ...
- spring中的BeanFactoryPostProcessor
spring中的BeanFactoryPostProcessor和BeanPostProcessor有些像,BeanPostProcessor是在bean的初始化前后进行一些操作, BeanFacto ...
- HanLP-朴素贝叶斯分类预测缺陷
文章整理自 baiziyu 的知乎专栏,感兴趣的朋友可以去关注下这位大神的专栏,很多关于自然语言处理的文章写的很不错.昨天看到他的分享的两篇关于朴素贝叶斯分类预测的文章,整理了一下分享给给大家,文章已 ...
- Pycharm 配置houdini
一.houdini开发环境配置 1.添加Python可执行文件 2.设置代码自动补全 刚刚添加的Python.exe,右侧点击加号,依次添加以上长方形中的文件,路径会根据个人安装路径有所变化,后面的目 ...