.NetCore2.1项目升级到.NetCore3.1的一点记录
前言
最近将近半个月没有更新博客了,因为找到了新的工作,开始上班了。上班之余也没闲着,上周末将自己去年的一个.NetCore2.1的框架升级到了3.1版本。在升级过程中还是出现了不少问题。有些是版本升级必须要解决的,有些是因为自己犯了强迫症,一定要将引用的Nuget包升级到当前最新版本。 这里就凭借记忆,记录下这次升级的点点滴滴吧。
框架引用的Nuget包
这里先将引用到的部分Nuget包罗列出来,都是常用的库。
- Autofac
- AutoMapper
- NewLife.Redis
- NLog
- System.Text.Json
- Microsoft.AspNet.SignalR
- DotNetCore.NPOI
- Quartz
- Swashbuckle.AspNetCore
升级到.NetCore 3.1出现的几个明显的问题
- 使用第三方IOC容器方式的改变导致依赖注入这一块代码需要改动
- Startup内提供内置的依赖注入服务有所改变,导致原有的部分方法编译可通过运行时则异常
- 跨域实现部分微软做了更细化的限制,原有的跨域部分代码运行时异常
依赖的组件出现的问题
- AutoMapper升级到9.0后因为官方移除了静态API导致所有引用到AutoMapper映射的地方都要改,同时需要将IMapper注入到DI容器内
- Swashbuckle.AspNetCore升级到5.1后API有所更新,需要重新编写部分代码,同时因为新增了一些特性可以将以前自定义的部分扩展删除
上面基本上是本次升级中碰到的一些问题,看上去感觉很好处理可是在实际代码中未必如此。一步一步说~
替换微软原生IOC容器导致的代码变更
首先看下原来的IOC容器是如何替换的
如上图的ConfigureServices
方法,该方法的签名是返回一个IServiceProvider接口,你可以粗略的把它当成一个IOC服务。
上面的关键代码是 return services.AddAutofacService();
它将一个已经Build后的IContainer
容器对象转成ILifetimeScope
对象返回给ConfigureServices
方法。
具体代码如下图:
其中RegisterDependencyService的职责是将指定的程序集动态注入到Autofac容器中,同时Build出容器。需要注意的是Autofac的ContainerBuilder对象在Build出IContainer
容器后是不允许再次通过该对象执行Update以及Build方法。
RegisterDependencyService代码如下图
需要留意RegisterDependencyService上面的AutoMapper的映射注入,后面升级AutoMapper后这一段代码会整改~
这就是原来.NetCore2.1的依赖注入以及微软原生依赖注入容器替换成Autofac的关键代码。
那么我的.NetCore 3.1版本的代码如何改变的?
首先看下3.1下面Startup下的ConfigureServices方法改成啥样了。
如下图:
ConfigureServices 方法签名不再有IServiceProvider 返回值,那如果需要更改原生的依赖注入容器要怎么做?系统采取类似提供一个回调方法,
在此方法内我们使用第三方依赖注入容器对服务进行注册,而且只需要注册,容器不需要你进行Build~
如下图,在Startup下新增如下方法
同时采取Autofac的ModuleRegistrationExtensions扩展类对服务进行注册,要求必须创建一个继承Autofac.Module的“模块”类,
在该模块类里执行所有的注入工作。模块类里面通过重写Load方法实现服务注册,如下图
这里要讲下AutoMapper在升级到9.0后将静态API都移除了,作者的意图也很明显,他认为开发者应遵循微软倡导的依赖注入方式去使用具体的服务,
所以没有办法,IMapper也得老老实实的进行服务注入,否则后续没得玩。
AutoMapper注入如下:
反射程序集找到所有映射Profile,然后注入映射了Profile的MapperConfiguration对象。再注入MapperConfiguration对象创建的IMapper对象。
至此解决了Autofac以及AutoMapper~
缓存问题
接下来就是缓存了,缓存其实主要是配置上的,如.NetCore2.1配置下我是这么配置的:
同样的代码在升级到3.1版本后运行时会出现下面异常:
The CORS protocol does not allow specifying a wildcard (any) origin and credentials at the same time. Configure the CORS policy by listing individual origins if credentials needs to be supported.
如何解决可以参考:
https://mykkon.work/how-to-setup-any-origin/
Swagger的相关变化
swager的改变有下面几点
移除了文件上传操作过滤器(新版本的Swagger已经支持包含文件上传的Aciton,不需要和以前一样继承IOperationFilter)
如以前是这么做的,创建一个继承IOperationFilter的过滤器
在AddSwaggerGen方法内引用它。
还有就是增加Swagger的认证和以前有所不同,参考
https://www.cnblogs.com/choii/p/12484544.html