如何移植.NET Framework项目至.NET Core?
公司的项目一直采用.NET框架来开发Web项目。目前基础类库均为.NET Framework 4.6.2版本。Caching, Logging,DependencyInjection,Configuration等基础设施相关的依赖库一直和官方保持同步,目前是1.1版本。.NET Core越来越趋于稳定,新的开发工具也在三月份发布。因此,计划将.NET Framework移植至.NET Core/Strandard。目的是使基于.NET开发的Web应用可以跨平台运行。
按应用场景将公司的项目分为基础类库,基础服务和应用项目。基础类库以包的形式提供各类基础功能。基础服务通过Wcf项目搭建或者通过Web API项目搭建。应用项目则是Web Mvc项目为主。基础类库和基础服务是以一个一个解决方案的形式存在。每个解决方案的结构,包含一个或者多个类库项目,一个或多个控制台项目,它们分别用于功能实现、单元测试、功能演示。如果全部要移植,那么优先级应该是基础类库 -> 基础服务 -> 应用项目。此次移植的对象是基础类库。
基础类库最终会以包的形式通过NuGet发布出去,目前只面向.NET Framework框架。移植的目标之一,是让包也能被面向.NET Core、.NET Standard框架的项目引用。结合官方资料,我选择了直接迁移的方案。即直接将项目文件转换为新的基于.NET Core的项目文件。下面详细说明移植的细节。
1. 新建基于.NET Core的项目。
首先重命名现有项目文件*.csproj为*.Net46.csproj。然后使用VS2017新建一个新的基于.NET Core的项目,项目类型可以是“类库(.Net Core)”或者“类库(.Net Standard)”。注意,VS2017会提示存在同名目录,所以创建时可以输入一个不同的名称,然后手工调整回来。
2. 编辑项目文件,使之支持面向多个目标框架。
通过VS2017 RC新建的项目,“类库(.Net Core)”或者“类库(.Net Standard)”,默认只有一个目标框架。我们可以编辑项目文件,使之支持面向多个目标框架。如支持目标框架为.NET Standard 1.4、.Net Core App 1.0和.NET Framework 4.5,则这样来修改。
<Project Sdk="Microsoft.NET.Sdk"><PropertyGroup><TargetFrameworks>netstandard1.4;netcoreapp1.0;net45</TargetFrameworks></PropertyGroup>
</Project>
注意,官方文档中提供了.NET支持的目标框架列表,你可以查询更多其他的目标框架。如果要兼容较低版本的框架,则目标框架版本不宜设置过高。如“net45”可用于.NET Framework 4.5 ~ 4.6.2等版本。如“net46”则只能用于.NET Framework 4.6 ~ 4.6.2等版本。
3. 修改应用程序代码相关API,使之支持多个目标框架。
a. 因目标框架提供的API不相同。故必要时可添加条件编译符号以便支持不同的运行时版本。
以下是常见的条件编译符号列表。
.NET Framework 2.0 --> NET20
.NET Framework 3.5 --> NET35
.NET Framework 4.0 --> NET40
.NET Framework 4.5 --> NET45
.NET Framework 4.5.1 --> NET451
.NET Framework 4.5.2 --> NET452
.NET Framework 4.6 --> NET46
.NET Framework 4.6.1 --> NET461
.NET Framework 4.6.2 --> NET462
.NET Standard 1.0 --> NETSTANDARD1_0
.NET Standard 1.1 --> NETSTANDARD1_1
.NET Standard 1.2 --> NETSTANDARD1_2
.NET Standard 1.3 --> NETSTANDARD1_3
.NET Standard 1.4 --> NETSTANDARD1_4
.NET Standard 1.5 --> NETSTANDARD1_5
.NET Standard 1.6 --> NETSTANDARD1_6
关于条件编译符号的应用,如以下代码:
using System; using System.IO; namespace Baza.NetStandardTester {public class PathHelper{public string BaseDirectory { get; set; }public PathHelper(){ #if NET45BaseDirectory = AppDomain.CurrentDomain.BaseDirectory; #endif}public string GetRootedPath(string path){string rootedPath = path ?? string.Empty;if (!Path.IsPathRooted(rootedPath)){if (string.IsNullOrEmpty(BaseDirectory))throw new ArgumentNullException("请先设置BaseDirectory属性");rootedPath = Path.Combine(BaseDirectory, rootedPath);}string directory = Path.GetDirectoryName(rootedPath);if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory)){Directory.CreateDirectory(directory);}return rootedPath;}} }
代码说明,PathHelper提供GetRootedPath方法用于根据相对路径计算出绝对路径。当运行时为.NET Core时,BaseDirectory属性需要手动设置。当运行时为.NET Framework 4.5时,由构造器对BaseDirectory属性进行赋值。注意System.AppDomain.CurrentDomain.BaseDirectory用于获取托管程序执行路径,类AppDomain只存在于.NET Framework中。
b. .NET Standard是个基于包的框架。当你需要某个API时,如IDataReader,你需要安装System.Data.Common包。如果是使用.NET Framework,则在命名空间System.Data下可以找到IDataReader而无需按照包。借助https://packagesearch.azurewebsites.net/工具,你可以快速定位某个API在哪个包中。
c. 基于.NET Core的项目,包版本号和其他元数据,都存储在*.csproj中,不会使用AssemblyInfo.cs文件,即移植时,这个文件可以删除。但是.NET Framework项目还是会继续使用该文件。
4. 同一解决方案,类库间的引用策略。
在引用类库时,要注意目标框架的兼容问题。如,“类库(.Net Standard)”项目,能够被.NET Core App、.NET Framework和其他.NET Standard项目引用。这个是因为.NET Core App和.NET Framework都支持相应版本的.NET标准库。下表显示了支持 .NET 标准库的整套 .NET 运行时。
平台名称 | Alias | ||||||||
---|---|---|---|---|---|---|---|---|---|
.NET Standard | netstandard | 1.0 | 1.1 | 1.2 | 1.3 | 1.4 | 1.5 | 1.6 | 2.0 |
.NET 核心 | netcoreapp | → | → | → | → | → | → | 1.0 | vNext |
.NET Framework | net | → | 4.5 | 4.5.1 | 4.6 | 4.6.1 | 4.6.2 | vNext | 4.6.1 |
Mono/Xamarin 平台 | → | → | → | → | → | → | → | vNext | |
通用 Windows 平台 | uap | → | → | → | → | 10.0 | → | → | vNext |
Windows | win | → | 8.0 | 8.1 | |||||
Windows Phone | wpa | → | → | 8.1 | |||||
Windows Phone Silverlight | wp | 8.0 |
注意,如果项目是面向多目标框架的,那么引用类库时,被引用类库也要支持面向多目标框架。
5. 单元测试
如果是使用.NET Framework类库项目来存放单元测试代码,那么可能会遇到一点问题。在VS2017 RC中,测试资源管理器无法识别出这些测试单元。通过新建“单元测试项目(.NET Framework)”,将生成的同名*.csproj覆盖原来的项目文件,测试管理器即可识别出来。
5. MSBuild自动编译新的解决方案
Windows下,按Release配置对整个解决方案编译。
"c:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe" XXX.sln /p:Configuration=Release;Platform="Any CPU"
会在相关类库根目录下\bin\Release目录中,生成net46和netstandard1.6两个目录。
6. 使用dotnet-nuget-push发布包
使用vs2017打包时,只需右击要打包的项目,选择“打包”,即可在.\bin\Debug或.\bin\Release下生成XXX.0[.0].0.nupkg文件,然后将这个文件.nupkg上传至nuget.org中。通过调用dotnet-nuget-push可以自动化这个发布过程,因此这种方式会更加方便。
dotnet nuget push XXX.0[.0].0.nupkg -k 4003d786-0000-4004-bfdf-c4f3e8ef9b3a -s http://customsource/
k:服务器的 API 密钥 s:服务器 URL,如发布到nuget.org,则可以这样写。
dotnet nuget push XXX.0[.0].0.nupkg -k 4003d786-0000-4004-bfdf-c4f3e8ef9b3a -s https://www.nuget.org/api/v2/package
通常在windows下,会将dotnet-nuget-push写在批处理文件中来完成基本类库的部署工作。
总结
通过此方案迁移后,最终保留新的解决方案和项目文件,旧的解决方案和项目文件在移植的过程中被删除。之后将按照新的解决方案来跨平台开发。基本类库的移植工作就介绍到这里。源代码的移植将是个挑战。譬如部分源码所引用的API在.NET Core框架下不存在时如何处理?另外,基础服务和Web Mvc项目的移植,因为要部署到linux中。也将会遇到各种问题。
参考资源
1. 组织项目以支持 .NET Framework 和 .NET Core
2. dotnet-nuget-push
3. packagesearch.azurewebsites.net
4. .NET 标准库
5. Developing Libraries with Cross Platform Tools
6. Target Frameworks
7. Porting to .NET Core from .NET Framework
转载于:https://www.cnblogs.com/dengzhizhong/p/6436213.html
如何移植.NET Framework项目至.NET Core?相关推荐
- 将 Net 项目升级 Core项目经验:(一)迁移Net项目为Net Core\Standard项目
迁移Net项目为Net Core\Standard项目 背景: 我们公司内部有自己ORM开发框架,最新因为需要将系统迁移到国产服务器上,所以首先需要将最基础的ORM框架改造可以运行在国产服务器上.对于 ...
- vs中如和根据项目生成类图_迁移WPF项目到.NET Core
综述# .NET CORE 3.0开始,桌面端支持WPF了.很多.NET FRAMEWORK的项目已经跑了一阵子了,不是很有必要支持.NET CORE,不过最近用一个程序,为了贯彻一些C# 8的特性, ...
- 将 .NET Framework 项目转换为 .NET Standard 项目
将 .NET Framework 项目转换为 .NET Standard 项目 独立观察员 2020 年 8 月 20 日 如今 .NET Core 是未来发展的主流(至少在 .NET 5 发布之前) ...
- 迁移Net项目为Net Core\Standard项目
背景: 我们公司内部有自己ORM开发框架,最新因为需要将系统迁移到国产服务器上,所以首先需要将最基础的ORM框架改造可以运行在国产服务器上.对于我们Net来说,优选Net Core.在迁移的过程中,将 ...
- 迁移.net framework 工程到.net core
在迁移.net core的过程中,第一步就是要把.net framework 工程的目标框架改为.net core2.0,但是官网却没有提供转换工具,需要我们自己动手完成了..net framewor ...
- 《你必须掌握的Entity Framework 6.x与Core 2.0》正式出版感想
前言 借书正式出版之际,完整回顾下从写博客到写书整个历程,也算是对自己近三年在技术上的一个总结,整个历程可通过三个万万没想到来概括,请耐心阅读. 写博.写书完整历程回顾 从2013年12月注册博客园账 ...
- WinForms项目升级.Net Core 3.0之后,没有WinForm设计器?
目录 .NET Conf 2019 Window Forms 设计器 2019 9.23-9.25召开了 .NET Conf 2019 大会,大会宣布了 .Net Core 3.0 正式版.这两天我也 ...
- 《你必须掌握的Entity Framework 6.x与Core 2.0》书籍出版
前言 到目前为止写过刚好两百来篇博客,看过我博客的读者应该大概知道我每一篇博客都沿袭着一贯的套路,从前言到话题最终到总结,本文依然是一如既往的套路,但是不是介绍技术,也可说是介绍技术,不过是介绍书中的 ...
- 使用 Android NDK 的交叉编译工具链移植 C/C++ 项目到安卓平台
什么是 NDK? Android NDK 是一套可以让开发者在安卓应用开发中使用 C/C++ 实现特定模块的工具集,不是所有应用都需要用到,但是正确地使用可以有效提高应用运行效率和安全性. 为什么要在 ...
最新文章
- lisp提取长方形坐标_求修改lisp程序,如何提取CAD中多个点的坐标,(本人想提取UCS坐标系)另外只需要提取X,Y值,不要Z...
- 大型网站架构不得不考虑的10个问题,互联网营销
- 【 FPGA 】FIR滤波器之 Hilbert 变换的实现
- CSS上下左右居中的几种方法
- 【已解决】Linux下安装MySQL数据库
- MATLAB机器学习系列-11:粒子群优化原理及其matlab实现
- c语言清空输入缓冲区函数,c语言:C语言清空输入缓冲区在标准输入(stdin)情况 -电脑资料...
- DevOps 国际峰会,为你讲解腾讯的 Git 转型之路
- 蓝色星空背景互联网网络科技PPT模板
- 文件 md5 查看 命令
- js或css指定元素点击时内容不可被选中
- python-78:对日期格式进行处理
- 输出100-1000之间的水仙花数 是三位数 水仙花数就是 每个位上的数字的三次方的和仍然为原数字 例如:153是一个“水仙花数“,因为153=1的三次方+5的三次方+3的三次方;
- Visio 2019 专业版安装教程
- java实现令牌桶算法
- 如何购买腾讯云学生服务器
- 52单片机C语言如何用间接寻址,单片机要如何寻址?
- JNA 中 String 转 Pointer
- 微信小程序项目实例——体质计算器
- Windows Server® 2008 Enterprise 组件服务 找不到 ”Microsoft Word 97 - 2003 文档“组件
热门文章
- 组件面板 html 页面,Html - Bootstrap Panel面板
- python的django介绍_【Python基础知识】Django框架简介
- python网络编程库_python网络编程学习笔记(9):数据库客户端
- 广东省计算机大赛设计什么时候,2017年广东省大学生计算机设计大赛
- 数据结构-----AVL树的旋转操作
- C++学习笔记-----operator=函数处理自赋值
- git reset git stash
- 二叉树的锯齿形层次遍历—leetcode103
- Linux多线程编程(一)---多线程基本编程
- Gossip协议详解