40

.NET Core迁移实践:项目文件csproj的转换

 3 years ago
source link: https://mp.weixin.qq.com/s?__biz=MzI1NDc0ODMzNg%3D%3D&%3Bmid=2247484867&%3Bidx=1&%3Bsn=e23a5fa5acc1ffe993e91665c43e4f0f
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

随着net core的不断更新和生产可用,公司原有基于.net framework的项目也早就在逐步迁移到net core平台。由于我们公司内部是大规模的应用net技术栈进行开发和交付的,因此迁移工作量是巨大的。但是千里之行始于足下,本文将分享迁移前置过程中的一个环节,给大家做一下参考。

背景说明

先来介绍一下什么是SDK样式的文件结构。关注net core发展的同学应该对早期的项目定义文件project.json还有点印象。.net开发组在net core 1.0版本时是准备抛弃xml格式的csproj文件而改为json格式的project.json来定义和描述项目的。但是后来主要由于MSBuild的兼容问题,不得不放弃project.json转移回xml格式的csproj。

然而由于传统.net framework的csproj文件内容繁杂,可读性和操作性较差,因此微软重新定义了新样式的csproj文件内容样式。其最大化的保持了和原有xml属性的兼容,并添加了一些新的特性。由于新格式的csproj文件总是以: <Project Sdk="Microsoft.NET.Sdk"></Project>标记来定义,所以称之为SDK样式。

一个典型的.net framework平台的csproj文件结构如下图所示:

uQN77ve.png!mobile

其中包含了项目的编译配置、调试生成配置、大量的nuget文件依赖、大量的cs源代码文件路径等,造成了此文件内容的非常繁多,阅读和分析都有比较大的困难。

而SDK样式的csproj文件内容就非常精简了,如下图所示:

rEBRJrA.png!mobile

其中TargetFrameworks配置项目的多目标平台,可选的值有netstandard2.1;net451;netcoreapp3.1,三种格式分别代表net standard、net framework、net core目标平台。此处的配置根据各人的项目定位不同设置所需的值。我们公司的业务程序是跑在特定的运行容器下的,迁移过程也是分阶段展开,最终我们采取先同时编译两个目标平台dll的方案。

由以上对比可见,SDK样式的csproj内容精简的一大原因就是文件的依赖(cs源码和nuget包文件)不需要在csproj中明确写明。针对cs源码及目录结构,VS自动识别项目目录内的文件结构作为项目结构,这一点改变真是点赞。因为文件及目录不需要csproj这个中间层再多一次描述,相当于“所见即所得”,相信大家在平时肯定遇到磁盘的源文件存在而VS项目就是看不到等类似问题,以后不会再有困惑啦。

另外针对nuget包依赖的文件也是如此,csproj不再维护nuget包内的文件明细,而改为PackageReference以nuget包为单位来管理依赖。这个改变对我们的转换几乎没有影响,重新添加一次nuget引用即可;同时再说一句:.NET Core是不支持packages.config文件管理nguet包,建议大家提前就将nuget包的管理改为PackageReference方式;

csproj文件转换的操作步骤

有了以上的背景说明,接下来的工作就是针对要迁移的项目csproj文件执行改造,其实微软也提供了一些辅助工具(dotnet try-convert等)来帮助迁移,但是必须先保证迁移操作明确和无误后,才能逐步使用特定的辅助工具来提高效率。具体操作如下:

    1. 直接备份原csproj文件然后将其清空

2. 然后粘贴如下最小化的xml代码:

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.1;net451</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
</ItemGroup>
</Project>

3. 调整的依赖nuget包和直接引用的程序集dll

这一步对nuget包有要求,需要其提供netstandard平台的版本,如下图:

vQJRVbE.png!mobile

如果是公司内部的nuget包就需要提前做好支持,而如果是依赖的第三方nguet包那就需要确认是否有.NET Core支持了。不过当前.NET Core已成趋势,绝大多数流行的nuget包都能够支持了。

  4. 检查和处理源代码中不兼容的部分

由于从.net framework迁移到.NET Core确实存在部分代码不兼容的地方,因此需要一一识别并寻找替代方案。微软官方提供了不兼容说明,大家可以参考本文末尾的链接【从 .NET Framework 迁移到 .NET Core 的中断性变更】。这里提供几种常见的不兼容情况:

  • CallContext不兼容:可以通过Asynclocal<T>替换解决。

  • 原System.ComponentModel.DataAnnotations不兼容:需要单独安装nuget包System.ComponentModel.Annotations即可解决。

  • System.Runtime.Remoting不兼容:暂无替换方案

5. 删除:AssemblyInfo.cs

6. 删除:packages.config文件

   7. 提醒:调整CI配置

输出目录Debug/Release目录内也分别生成了netstandard2.1和net451的2套程序集。因此假如应用了CI的话,相关设置也需要更新。

完成以上操作后,项目的结构就变成了下图的样子,这样编译通过后会生成针对特定目标平台的程序集。

zUNfUnU.png!mobile

总结

本文首先介绍了SDK样式的csproj文件的背景,并详细介绍了从传统.net framework项目转换到.NET Core项目的关键步骤。根据各企业的项目规模和应用场景的不同,还需要制订合理的迁移计划,配合严格的测试工作,这样才能保证迁移工作的稳定推进,尤其要避免的是因迁移.NET Core而带来服务异常甚至是生产事故。

祝大家迁移顺利!

参考资料

  • .NET Core迁移前的准备工作

  • 从 .NET Framework 迁移到 .NET Core 的中断性变更

  • 从 .NET Framework 移植到 .NET Core 的概述

  • .NET可移植性分析器

  • .NET API 分析器


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK