.Net Core爬坑记(上)

最近公司有将Windows下运维服务节点移植到Linux系统下的动作,而在代码不做过大改动的情况下,最合适的方案貌似就剩下了跨平台移植。因为之前的运维服务节点就是基于.NET Framework写的,所以考虑到微软的跨平台方案,貌似只有.Net Core了。本文把移植过程中的遇到的难点(.Net Core小白,第一次接触,所以几乎都是难点)记录下来,做个整理。

什么是.Net Core跨平台?

.NET Core 是开放源代码通用开发平台,由 Microsoft 和 .NET 社区在 GitHub 上共同维护。 它支持跨平台(支持 Windows、macOS 和 Linux),并且可用于生成设备、云和 IoT 应用程序。

这个跨平台其实是“半跨平台”。考虑到Windows和Linux的平台特殊性(比如,Windows有注册表而Linux没有),所以,不可能指望把整套项目改变目标框架就实现跨平台运行,项目多多少少还是要改滴。微软的工程师考虑到了这一点,所以推出了一个分析器,这个软件的目的就是分析你当前的项目有百分之几可以不用任何改动移植到.Net Core。这个分析器的名字叫.NET Portability Analyzer, 在VS 2017 "工具"-》"扩展和更新"中可以搜索到并安装。

.Net Core爬坑记(上)_第1张图片
.NET Portability Analyzer

用法也很简单。只要在你的解决方案管理器中右键你的项目,然后选择"Analyze Project Portability"(无外部引用)或者"Analyze Project Portability (with project references)"(有外部引用),然后软件会为你生成一个Results文件的弹窗,然后打开xml文件,就可以看到移植的可能性。

.Net Core爬坑记(上)_第2张图片

在评估了项目迁移的可行性以后,下面就是正式的项目迁移了。

正式迁移

.Net Core只支持两种客户端模式的开发:控制台程序(Console App)和类库(dll)。也就是说,如果你的项目是WPF、Winform、WCF程序的话,对不起,你的项目不适合跨平台移植,老老实实的写Linux下原生应用吧。当然,我们的项目是基于控制台的,所以有移植的可能性。

首先,打开VS2017,新建一个Visual C# -》.Net Core,选择控制台程序项目。然后将里面的.cs文件代码删除,然后项目上右键选择"添加"-》"现有项",然后找到你准备迁移的项目中的.cs文件,然后在"添加"按钮的下拉框下选择"添加为链接"。为什么要选择这一项呢?因为选择这个的时候,不需要复制原有项目文件,而且还能跟复制项目文件起到一样的效果。

刚才说过,代码不是100%可以被移植到Linux平台的。也就是说,里面有一些代码是平台特有的,这时候就要使用条件编译了。简单的说就是if是.Net Core的程序,执行这些平台的特殊操作,else执行项目原有的操作逻辑。使用的宏定义为

#if NETCOREAPP2_1

    [PlatformBehavior]

#else

    [ServiceBehavior]

#endif

也就是说,在你项目中涉及到操作系统底层相关的API时,你可以使用这个宏定义进行条件编译,从而保证项目在两个平台上都可以正常运行,从而实现跨平台。

在跨平台时,不得不提的就是.Net Core和项目原本框架.Net Framework的关系。引用官方文档的原话:

.NET Core and the .NET Framework have (for the most part) a subset-superset relationship. .NET Core is named "Core" since it contains the core features from the .NET Framework, for both the runtime and framework libraries. For example, .NET Core and the .NET Framework share the GC, the JIT and types such as String and List. We'll continue improving these components for both .NET Core and .NET Framework.

.NET Core was created so that .NET could be open source, cross platform and be used in more resource-constrained environments. We have also published a subset of the .NET Reference Source under the MIT license, so that you and the community can port additional .NET Framework features to .NET Core.

从官方文档可以看出,.NET Core 是从 .NET Framework 演化而来,有点像父类-子类关系,而不是子集关系。这意味着什么?很多.NET Framework的API在.Net Core中是无法使用的

.Net Core爬坑记(上)_第3张图片
关系图1


.Net Core爬坑记(上)_第4张图片
关系图2

所以说,这就是最难办的地方。目前,我的解决方式有三个:

1)在Nuget中下载对应的包,举个例子:

原项目中用到了System.Management中的相关API,但是在.Net Core中并没有直接提供System.Management的类库,所以从Nuget中下载下来就可以直接使用原本只能在.Net Framework中的关于System.Management相关API。

2)如果引用第三方,那么对不起,找到第三方库的源代码,自行编译.Net Core版本的,举个例子:

原项目中用到了agsXmpp,是基于.Net Framework 4.0的,那么找到它的源代码,按照代码移植和条件编译的方法编译出.Net Core版本的。

3)在https://github.com/dotnet/corefx/wiki/ApiCompat中寻找API的使用方式和平台特性。

如果这些都不可行的话,那么需要考虑这个项目中的这些功能是否有跨平台的必要性。如果势必需要,可以考虑前面所说的用平台的原生开发来代替跨平台。

先写到这里吧,后面还有很多遇到的难点,往后一一整理吧,谢谢!

你可能感兴趣的:(.Net Core爬坑记(上))