.NET Frameworkのプロジェクトを.NET Standardに移行する

# はじめに
.Net Frameworkで開発したプログラムを、.NET Standardに移行して複数プラットフォームで利用できるようにしたいと考える場合があります。
本稿は、.NET Frameworkのプロジェクトを.NET Standardに移行するためのノウハウの紹介です。
なお、.NET Coreも同様の方法で移行できます。
(本稿は、私がとあるアプリケーションのモデル層を、.NET Frameworkから.NET Starndardに移行した経験を元に執筆しています)

# 移行方法

## 基本方針
以下の2つのガイドの内容に従って、移行します。以降は、ポイントとなる部分のみ記載します。
[.NET Framework から .NET Core にコードを移植する](https://docs.microsoft.com/ja-jp/dotnet/core/porting/)
[方法: WPF デスクトップ アプリを .NET Core に移植する](https://docs.microsoft.com/ja-jp/dotnet/core/porting/wpf)

## 計画を立てる
.NET Framework のソースコードが.NET Standard にどれだけ容易に移行できそうなのか、準拠率を調べるツール「Portability Analyzer」で計測します。
ちなみに、私が移行したアプリケーションのモデル層は、10年近く前に開発したプロジェクトですが準拠率90%でした。従って、最近開発したプロジェクトであれば、準拠率はもっと高いと思います。
[.NET Portability Analyzer](https://docs.microsoft.com/ja-jp/dotnet/standard/analyzers/portability-analyzer)

## Windows 互換機能パックのインストール
普通に.NET Standardに移行しただけだと、.NET Frameworkに存在し、.NET Standardに存在しないクラスやメソッドがあるため、ビルドエラーが大量に発生します。
そこで、これをインストールします。そうすると、.NET Frameworkに存在していたメソッドの多くが同じ名前で.NET Standard用に利用できます。これをインストールせずに全て手動でビルドエラーを解消するのは大変だと思います。詳細は以下を参照ください。
[Windows 互換機能パックを使用してコードを .NET Core に移植する](https://docs.microsoft.com/ja-jp/dotnet/core/porting/windows-compat-pack)

## 非推奨のAPIの検出
.NET Framework から .NET Standardに移行した際に、非推奨のAPIを検出するのが .NET API アナライザーです。これをインストールすることで、ビルド時に警告として表示します。
逆に、これをインストールしないと、Windows以外のプラットフォームで動作するのかどうか、静的な判断ができません。LinaxやMacOSで動作させることも目的であれば、これをインストールして、警告をすべて解消する必要があります。
なお、一部の環境(例えば、MacOS)を動作対象にしない場合は、プロジェクトファイルにPlatformCompatIgnore属性を指定することで、その環境での動作に対する警告を表示しないようにできます。

```xml
<PropertyGroup>
    <PlatformCompatIgnore>macOS</PlatformCompatIgnore>
</PropertyGroup>
```

詳細は以下を参照ください。
[.NET API アナライザー](https://docs.microsoft.com/ja-jp/dotnet/standard/analyzers/api-analyzer)

# テストプロジェクトからの参照
従来、.NET Frameworkのプロジェクト内のinternalなクラスやメソッドに対して単体テストをする際には、AssemblyInfo.cs に InternalsVisibleTo という属性を設定することで、単体テストプロジェクトからinternalなメンバーにアクセスできました。
しかし、.NET StandardにはデフォルトでAssemblyInfo.csが存在しません。そのため、手動で AssemblyInfo.cs を作成し、上記の属性をします。詳細は以下を参照ください。
[.NET StandardプロジェクトでInternalsVisibleToを設定する方法](https://www.nuits.jp/entry/net-standard-internals-visible-to)

# COMとして参照可能にする
.NET Standardは、複数プラットフォームで利用するためのライブラリです。そのため、.NET Standard のプロジェクトをWindows専用の技術である COMとして参照可能にすることは、あまりありません。
しかし、既存のレガシーコードから.NET Standardに移植した場合、COM参照可能にしたい場合があります。
そういう場合は、以下の記事を参照ください。.NET Standard のメンバーをCOMとして公開する例が示されています(こちらは試したことありません)。
[Can you make a .NET Standard assembly COM-Visible?](https://github.com/dotnet/standard/issues/412)

# .NET FrameworkのDLL参照について
.NET Standard のプロジェクトは .NET FrameworkのDLLを参照できます。ただ、その場合、.NET Framework上で動作させるアプリケーションでは動作しますが、それ以外の環境では実行時にエラーになると思います。
複数プラットフォームで動作させたい場合は、参照するDLLも.NET Standardにする必要があります。
その辺りの詳細は、下記を参照ください。
[動作する仕組みは、こちらのスライドのP27～P33を参照](https://www.slideshare.net/AtsushiNakamura4/visual-studio-2019wpf-on-net-core-30)
[WPFアプリを.NET Coreに移行したい場合の例はこちらを参照](https://qiita.com/soi/items/e1cf2abf9845164bf439#net-framework%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E3%81%AE%E4%BD%BF%E7%94%A8)

# まとめ
上記方法で、.NET Frameworkのプロジェクトを.NET Standardに移行できます。

ちなみに私は [Lightning Review というレビュー支援ツール](https://www.lightning-review.com/) を開発しています。
Twitterでも開発に役立つ情報を発信しています → [@kojimadev](https://twitter.com/kojimadev)