把旧的 csproj 移转至 .NET Core 2.0 项目

我挑了一个先前写的小工具,来试试看把它从原本的 .NET Framework 4.5 改成 .NET Core 2.0 平台会碰到那些问题。移转过程顺便引入第三方套件来改进代码。这里也顺便记一下那些好用的套件。

简介

挑选来移转至 .NET Core 2 的项目是我先前已经放在 GitHub 的 Chinese-Converter。这是个命令行工具,可以将指定的档案进行简繁/繁简中文的转换。

原本我是以偷懒的作法,调用 Microsoft Word 来帮我做第一轮的简繁转换,然后再用我自己维护的简繁对应辞库进行第二轮的补强修正。既然 .NET Core 的重点在于跨平台,那么自然就得去除对 MS Word API 的依赖。于是,除了修改 csproj 项目的内容,我还得修改一些代码。长话短说:我打算用(新?)同文堂的辞库。

关于同文堂的简繁对应辞库,我在 GitHub 上面至少找到三个。于是我又在我的项目里面增加一个工具:MergePhrase,用来合并从各方搜集来的简繁词汇对照档。目标是集成成单一档案,作为 ChineseConverter 的自带辞典,然后再以其他行业的术语辞库作为额外的补强。

关于 ChineseConverter 的部分说得够多了。看一下跟 .NET Core 有关的部分吧。摘要如下:

  • 修改 .csproj 档案
  • 使用 Serilog 来输出 log
  • 部署

修改 .csproj 档案

ChineseConverter 原本是针对 .NET Framework 4.5 来编译的。现在要改成针对 .NET Core 2.0 平台。

我用 Visual Studio 2017 开启项目的「属性」,在「Target framework」下拉列表里面只会出现 .NET Framework 各版本,而没有 .NET Core 的选项。我的直觉反应就是去手动修改 .csproj 档案。(也许有工具可以处理这件工作?)

注:这里纯粹是描述我对这个项目的做法,不见得适用所有类型的 .NET 项目。

首先,把开头的这几行:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProjectGuid>{B395A62E-B988-4370-AB66-D76A4FC49C9E}</ProjectGuid>
    <OutputType>Exe</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>ChineseConverter</RootNamespace>
    <AssemblyName>tscc</AssemblyName>
    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
  </PropertyGroup>

替换成:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <RootNamespace>ChineseConverter</RootNamespace>
    <AssemblyName>tscc</AssemblyName>
	<TargetFramework>netcoreapp2.0</TargetFramework>
  </PropertyGroup>

然后把包含 <Compile Include> 项目的 <ItemGroup> 区块整个删除,例如:

  <ItemGroup>
    <Compile Include="TSChineseDictionary.cs" />
    <Compile Include="Program.cs" />
    <Compile Include="Properties\AssemblyInfo.cs" />
    <Compile Include="TSChineseConverter.cs" />
  </ItemGroup>

此时用 Visual Studio 2017 开启项目,看一下项目属性里面的 Target framework,竟然变成了 .NET Framework 4.0。

后来我把 .csproj 里面的这行删除:

  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

然后用 Visual Studio 2017 开启项目,Target framework 就变成 .NET Core 2.0 了。如下图:

接着尝试建置项目,出现一些编译错误。根据错误讯息所提供的线索,我删除了 AssemblyInfo.cs,然后开启项目的「属性」,切换至「Package」,并输入套件的名称、版本等数据:

到这个步骤做完,这个项目就可以建置成功了。

剩下的工作,就是把一些不兼容于 .NET Core 2 的套件或代码改掉。在这当中,我移除了对 Microsoft.Office.Interop.Word.dll 的依赖,同时加入以下套件:

上述套件,Json.NET 和 Command Line Parser 的 .NET Core 版本在用法上跟以前没有明显差异,网络上可以找到很多文章。至于 Serilog 的部分,我尝试把它跟 .NET 的 dependency injection API 接在一起用,所以就顺便在此纪录一下 Serilog 的用法。

使用 Serilog 来输出 log

这里会用到的套件/组件有:

  • Microsoft.Extensions.DependencyInjection 2.1.0-preview-final
  • Serilog 2.7.1-dev-00960
  • Serilog.Extensions.Logging 2.0.2
  • Serilog.Sinks.File 4.0.1-dev-00795

Step 0: 建立一个 .NET Core Console 应用程序项目

Step 1: 加入套件

使用 NuGet Manager 或下列指令来安装所需之套件:

Install-Package -IncludePrerelease Microsoft.Extensions.DependencyInjection Install-Package -IncludePrerelease Serilog Install-Package -IncludePrerelease Serilog.Extensions.Logging Install-Package -IncludePrerelease Serilog.Sinks.File

完成后,项目的 .csproj 档案里面会加入以下内容:

<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.1.0-preview1-final" />
<PackageReference Include="Serilog" Version="2.7.1-dev-00960" />
<PackageReference Include="Serilog.Extensions.Logging" Version="2.0.2" />
<PackageReference Include="Serilog.Sinks.File" Version="4.0.1-dev-00795" />

Step 2: 修改 Program.cs

Main 函式中加入

// 设定 DI
var serviceProvider = new ServiceCollection() 
    .AddLogging(loggingBuilder => loggingBuilder.AddSerilog(dispose: true))
    .BuildServiceProvider();

// 建立 logger
Log.Logger = new LoggerConfiguration()
    .Enrich.FromLogContext()
    .WriteTo.File(opts.LogFileName, Serilog.Events.LogEventLevel.Information)
    .CreateLogger();

其中第二行代码的 ServiceCollection 是来自 Microsoft.Extensions.DependencyInjection。这些代码主要是参考自 Serilog 官方范例,用法挺简单。

由于我只需要把 log 写入至档案,所以这里使用了 .WriteTo.File(...)。Serilog 还支持多种输出目标/格式,需要时可参阅官方文件。

Step 3: 写 log

一旦完成了 Serlog 的初始化设定,接着就可以直接通过 Log 类型来输出 log 字符串了。例如:

Log.Information("应用程序开始执行。");

Log 类型有个静态属性: Logger,其类型为 ILogger。由此可见,我们也可以把 Log.Logger 对象注入到其他类型。底下是「构造函数注入」的例子,直接取自 ChineseConverter 项目:

var dict = new TSChineseDictionary(Log.Logger);

TSChineseDictionary.cs 里面,构造函数需要接受一个 ILogger 参数,如下:

public class TSChineseDictionary
{
    public TSChineseDictionary(ILogger logger)
    {
        _logger = logger;
    }
}

注:Serilog 的一大特色是能够输出「结构化 log 讯息」方面的能力,这里没有用到。

部署

程序大致改好之后,我是通过 Solution Explorer 里面对项目名称点右键、选择 Publish 的方式来产生部署所需的档案。默认情况下,Visual Studio 会将此应用程序执行时所需要的档案放在项目的 bin\Release\PublishOutput\ 目录下。

注:如果开启命令窗口,将现行目录切换至项目的 bin\Debug\netcoreapp2.0\,然后用 dotnet myapp.dll 的方式来执行应用程序,可能会因为缺少其他相依组件而无法执行。

小结

由于我的这个 console app 项目只是个小工具而已,程序并不复杂,需要的第三方套件也都能找到支持 .NET Core 2 的版本,所以整个移转过程算是蛮顺利的。

文中没有提到的是,同一个 solution 里面还有一个单元测试项目。我同样把它改成 target .NET Core 2.0,但采用了不同的方法:这次我是重新建立一个新的单元测试项目,再把档案加进去。我觉得这样反而简单、干脆。

完工以后,又上网搜了一下,发现也有类似的心得分享,而且更详细。附在下方的〈延伸阅读〉。

再补充一下 ChineseConverter 的进度:目前已经把网络上搜集来的三个简繁对应辞库档案合并好了。由于转换的核心代码尚未改完,故仍放在工作分支,尚未合并至 master。此间,亦曾与同文堂的开发团队成员接触,询问辞库的问题。也许将来有机会再把字典文件的部分进一步完善吧。

Happy coding!

延伸阅读

转载于:https://my.oschina.net/u/3798404/blog/1647075

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值