ABP开发框架前后端开发系列---(16)ABP框架升级最新版本的经验总结
有一小段时间没有持续升级ABP框架了,最近就因应客户的需要,把ABP框架进行全面的更新,由于我们应用的ABP框架,基础部分还是会使用官方的内容,因此升级的时候需要把官方基础ABP的DLL进行全面的更新,以及对应的引用DLL也同步更新才行。不过在升级过程中还是很多奇奇怪怪的问题,本篇随笔针对出现的情况进行一系列的总结,以便后面有一个对照参考吧。
1、最新案例源码和NugGet程序包更新
ABP官方的基础模块更新速度还是很快的,一段时间过去,就跳过了几个版本号,我是在旧版本的基础上进行手动的NugGet更新,但是基于VS的Nugget总是更新卡顿,不知不觉就没有反应了,严重影响开发的效率。因此先从官方下载的Demo案例中把相关部分源码进行更新。
官方的案例源码下载地址是:https://aspnetboilerplate.com/Templates
1)最新案例源码结构和部分内容调整
我们从其中下载对应的源码,然后根据项目结构中的对应源码文件,使用Beyond Compare对比文件进行文件逐一对比,原则上除了个人扩展的部分,都以官方的源码做法为准即可。
目前ABP官方最新的DLL版本是5.3.0,可以下载的Demo版本是5.2.0,它们应该差别不大。下载下来的Aspnet-core部分的源码结构如下所示。

而我们的ABP框架是在这个基础上进行一定的结构优化,以更加方便快速的开发,以及结合代码生成工具进行快速的使用。
我们的VS项目结构 如下所示。

以上是VS里面解决方案的项目结构,我根据项目之间的关系,整理了一个架构的图形,如下所示。

上图中,其中橘红色部分就是我们为各个层添加的类或者接口,分层上的序号是我们需要逐步处理的内容。
应用服务层是整个ABP框架的灵魂所在,对内协同仓储对象实现数据的处理,对外配合Web.Core、Web.Host项目提供Web API的服务,而Web.Core、Web.Host项目几乎不需要进行修改,因此应用服务层就是一个非常关键的部分,需要考虑对用户登录的验证、接口权限的认证、以及对审计日志的记录处理,以及异常的跟踪和传递,基本上应用服务层就是一个大内总管的角色,重要性不言而喻。

回顾了解一下我们改造过的ABP开发框架的结构后,我们返回到版本升级的主体上来介绍。
目前我把VS的版本升级到最新,其.net framework支持4.8, 并单独安装了dotnetcore最新版本3.1,因此环境是最新的,而基础的ABP 5.3.0也是采用了.net core3.1。
对比源码,我们可以发现,Web.Host和Web.Core项目里面已经有所差异,IHostingEnvironment已经被抛弃使用,而采用dotnetcore最新对象IWebHostEnvironment来替代了。

替换最新源码为

因此Web.Host项目中的Module类也进行了调整。

相对应的Web.Core项目里面的Module也同时进行调整了。

2)NugGet程序包更新
Nugget程序包的更新,原则上可以选择单个项目进行更新,或者选择整个解决方案进行程序包的更新,前者可能相应速度快一些,后者由于解决方案项目数量问题,可能会较慢。
我早期的基础ABP版本是4.9,因此想一次性整个的解决方案的程序包进行更新,不过尝试多次,花了几个小时,都无法顺利进行项目的全部更新,于是单个项目进行更新,也非常慢。
于是也通过推荐采用Nugget最新地址进行更新,如下设置更新源。

在程序包源中添加:https://api.nuget.org/v3/index.json

响应速度相对快了一些,没有不经常的出问题了。
我们如果需要单独更新某个项目的程序包,那么需要选择项目,选择【管理Nugget程序包】进入界面更新即可。如下界面所示。


一般情况下,我们推荐对整个解决方案进行全面的程序包更新,如下选择解决方案,然后进入对应Nugget程序包管理界面更新即可。

这样的全部更新解决方案的程序包,如果能够顺利完成,那是皆大欢喜,不过可能会稍微慢一些。如果不行,只有逐个更新程序包了。
我之前选择这样的方式更新的时候,总是有一两个程序包更新出错,因此只有使用npm 控制台进行单独的升级了。

2、ABP框架基类封装接口命名调整
在更新ABP基础模块的时候,发现ABP的基础接口全部调整了命名,如原来的Get变为GetAsync,GetAll变为 GetAllAsync,Delete变为了DeleteAsync,Update变为了UpdateAsync,Create变为了CreateAsync。
也就是说,他们全部采用了异步名称的命名规则,在异步方法后面全部加上了Async作为标识。
我在之前模块介绍过ABP框架的基础接口。IAsyncCrudAppService定义了几个通用的创建、更新、删除、获取单个对象和获取所有对象列表的接口,接口定义如下所示。
namespace Abp.Application.Services
{
public interface IAsyncCrudAppService<TEntityDto, TPrimaryKey, in TGetAllInput, in TCreateInput, in TUpdateInput, in TGetInput, in TDeleteInput> : IApplicationService, ITransientDependency
where TEntityDto : IEntityDto<TPrimaryKey>
where TUpdateInput : IEntityDto<TPrimaryKey>
where TGetInput : IEntityDto<TPrimaryKey>
where TDeleteInput : IEntityDto<TPrimaryKey>
{
Task<TEntityDto> Create(TCreateInput input);
Task Delete(TDeleteInput input);
Task<TEntityDto> Get(TGetInput input);
Task<PagedResultDto<TEntityDto>> GetAll(TGetAllInput input);
Task<TEntityDto> Update(TUpdateInput input);
}
}
现在这些接口全部调整如下所示了。
namespace Abp.Application.Services
{
public interface IAsyncCrudAppService<TEntityDto, TPrimaryKey, in TGetAllInput, in TCreateInput, in TUpdateInput, in TGetInput, in TDeleteInput> : IApplicationService, ITransientDependency
where TEntityDto : IEntityDto<TPrimaryKey>
where TUpdateInput : IEntityDto<TPrimaryKey>
where TGetInput : IEntityDto<TPrimaryKey>
where TDeleteInput : IEntityDto<TPrimaryKey>
{
Task<TEntityDto> CreateAsync(TCreateInput input);
Task DeleteAsync(TDeleteInput input);
Task<PagedResultDto<TEntityDto>> GetAllAsync(TGetAllInput input);
Task<TEntityDto> GetAsync(TGetInput input);
Task<TEntityDto> UpdateAsync(TUpdateInput input);
}
}
那么这些我们都必须随着ABP框架的调整也同时进行接口和对应类实现的调整了。
例如对应的异步ApplicationService服务的基类封装,我们也需要调整对应的异步接口实现。

针对远程调用的ApiCaller接口和实现,我们也需要进行命名方面的统一调整,这样才能顺利进行异步接口的调用

我在之前随笔《ABP开发框架前后端开发系列---(10)Web API调用类的简化处理》有针对API调用层的简化处理做了说明,我们所有的API调用,基本都是通过统一的一个函数进行调用的。
统一调用处理的方法名称是DoActionAsync。

虽然由于前面介绍了应用服务层的接口很多接口增加了Async的后缀字符,但是客户端通过URL调用,这个Async是不需要的,也就是需要移除,我们之前组装的URL地址是根据函数名称,那么函数名称需要移除这个后缀的Async字样了。

这样系统就顺利跑起来了。服务端界面如下所示。

我们启动Winform客户端,界面如下所示。

登陆启动后主体界面如下所示

ABP开发框架前后端开发系列---(16)ABP框架升级最新版本的经验总结的更多相关文章
- ABP开发框架前后端开发系列---(14)基于Winform的ABP快速开发框架
前面介绍了很多ABP系列的文章,一步一步的把我们日常开发中涉及到的Web API服务构建.登录日志和操作审计日志.字典管理模块.省份城市的信息维护.权限管理模块中的组织机构.用户.角色.权限.菜单等内 ...
- ABP开发框架前后端开发系列---(3)框架的分层和文件组织
在前面随笔<ABP开发框架前后端开发系列---(2)框架的初步介绍>中,我介绍了ABP应用框架的项目组织情况,以及项目中领域层各个类代码组织,以便基于数据库应用的简化处理.本篇随笔进一步对 ...
- ABP开发框架前后端开发系列---(2)框架的初步介绍
在前面随笔<ABP开发框架前后端开发系列---(1)框架的总体介绍>大概介绍了这个ABP框架的主要特点,以及介绍了我对这框架的Web API应用优先的一些看法,本篇继续探讨ABP框架的初步 ...
- ABP开发框架前后端开发系列---(10)Web API调用类的简化处理
在较早期的随笔<ABP开发框架前后端开发系列---(5)Web API调用类在Winform项目中的使用>已经介绍了Web API调用类的封装处理,虽然这些调用类我们可以使用代码生成工具快 ...
- ABP开发框架前后端开发系列---(5)Web API调用类在Winform项目中的使用
在前面几篇随笔介绍了我对ABP框架的改造,包括对ABP总体的介绍,以及对各个业务分层的简化,Web API 客户端封装层的设计,使得我们基于ABP框架的整体方案越来越清晰化, 也越来越接近实际的项目开 ...
- ABP开发框架前后端开发系列---(4)Web API调用类的封装和使用
在前面随笔介绍ABP应用框架的项目组织情况,以及项目中领域层各个类代码组织,以及简化了ABP框架的各个层的内容,使得我们项目结构更加清晰.上篇随笔已经介绍了字典模块中应用服务层接口的实现情况,并且通过 ...
- ABP开发框架前后端开发系列---(11)菜单的动态管理
在前面随笔<ABP开发框架前后端开发系列---(9)ABP框架的权限控制管理>中介绍了基于ABP框架服务构建的Winform客户端,客户端通过Web API调用的方式进行获取数据,从而实现 ...
- ABP开发框架前后端开发系列---(9)ABP框架的权限控制管理
在前面两篇随笔<ABP开发框架前后端开发系列---(7)系统审计日志和登录日志的管理>和<ABP开发框架前后端开发系列---(8)ABP框架之Winform界面的开发过程>开始 ...
- ABP开发框架前后端开发系列---(8)ABP框架之Winform界面的开发过程
在前面随笔介绍的<ABP开发框架前后端开发系列---(7)系统审计日志和登录日志的管理>里面,介绍了如何改进和完善审计日志和登录日志的应用服务端和Winform客户端,由于篇幅限制,没有进 ...
随机推荐
- 001.前端开发知识,前端基础HTML(2020-01-07)
一.开发工具: chrome . sublime . photoshop 二.Web标准:不是某一个标准,而是由W3C和其他标准化组织制定的一系列标准的集合. 三.HTML的语言语法骨架格式 < ...
- Codeforces Round#615 Div.3 解题报告
前置扯淡 真是神了,我半个小时切前三题(虽然还是很菜) 然后就开始看\(D\),不会: 接着看\(E\),\(dp\)看了半天,交了三次还不行 然后看\(F\):一眼\(LCA\)瞎搞,然后\(15m ...
- Python练习五-函数
1.简述普通参数.指定参数.默认参数.动态参数的区别1)普通参数中,有形参和实参,其中形参是定义函数时写的参数,实参是调用函数时传给函数的参数:2)默认参数是在定义函数时,参数设定一个默认值:3)指定 ...
- TCP\IP协议簇-各层主要协议帧格式
本文只是对各协议的概要,详细请参考rfc文件. 官方下载地址:https://tools.ietf.org/rfc/index rfc中文:http://man.chinaunix.net/devel ...
- java连接access的用户名、密码异常Decoding not supported解决
Java通过ucanaccess对Access数据库.accdb文件连接: public static Connection getConn() { try { String dbURL = &quo ...
- 在Linux生成公钥后,使用git拉代码仍然需要密码的问题
一顿回车生成公钥后,用git拉代码还是需要输入密码 原因比较简单,在于.ssh 文件夹 及 authorized_keys文件的权限问题,全部修改为 700 即可,用下面命令 chmod -R 700 ...
- Rx系列---响应式编程
Rx是ReactiveX的简称,翻译过来就是响应式编程 首先要先理清这么一个问题:Rxjava和我们平时写的程序有什么不同.相信稍微对Rxjava有点认知的朋友都会深深感受到用这种方式写的程序和我们一 ...
- 吴裕雄--天生自然 HADOOP大数据分布式处理:添加主机和服务器的域名映射
- 树状数组 hdu2689 hdu2838
题意:给定一个正整数n,和一个1-n的一个排列,每个数可以和旁边的两个数的任意一个交换,每交换一次总次数就要加一,问将这个排列转换成一个递增的排列需要多少次交换? 题意可以转换成求这个排列的逆序对数. ...
- python中字母与ASCII码之间的转换以及进制间的转换
字母与ascii码: ord(c):参数是长度为1的字符串,简称字符.当参数为统一对象时(unicode object),返回能代表该字符的统一编码,当参数为8比特的字符串时,返回该字节的值.例如,o ...