はつねの日記

Kinect, Windows 10 UWP, Windows Azure, IoT, 電子工作

.NET Frameworkから.NET 6への移植は別ソリューションで!

.NET Frameworkで作成していたWPFアプリを.NET 6化しています。
.NET 6用の空のプロジェクトを.NET Frameworkのプロジェクトファイルのあるフォルダに新規に作成して、あとは、プロジェクトに既存のソースコードを追加してビルドが通れば、.NET 6化が完了します。

もちろん、動作時の一部非互換もありますので、ビルドしただけじゃなくて、そのあとにいわゆるシステムテスト的なテストで動作が変わっていないかの検証は必要です。
例えば有名なところだと、.NET 5以降についてはNLSじゃなくてICUが使われるようになった点などがあります。文字列のソートなどでカルチャー指定していないコードだとちょっと注意して動作を確認したほうがいいかもしれません。
グローバリゼーションと ICU | Microsoft Docs

ただし、ほぼ、非互換はないのでいくつかの注意点はありますが、プロジェクトファイルを.NET Framework版と.NET 6版に分けておけば、同じソースコードでそれぞれのビルドが通るようにできますので、移行期間のようなときも別々のソースコードを書いてなどは大筋では不要です。
それでも.NET 6のときのみに必要なコードなどが書きたくなったら

#if NETCOREAPP
#endif

のように「NETCOREAPP」のときのみを指定してあげれば実現できます。

### 問題点
こんな感じですごく順調に移行ができていたのですが、.NET Frameworkのプロジェクトファイルと.NET 6のプロジェクトファイルを同一ソリューションにいれてあげたときに問題が発生しました。
別々のソリューションだったときには問題なかったのですが、同一ソリューションにしてあげるとobjフォルダの中に自動生成される「project.assets.json」ファイルの内容がビルドするプロジェクトに応じた内容に変更されず、後からビルドした方のプロジェクトでビルドエラーが発生するようになるのです。
理由としては、project.assets.jsonの中のtargesに動作フレームワークごとにnugetするバージョンなどが記載されるのですが、これが.NET Frameworkのみか.NET 6のみかのどちらかだけしか生成されず両方を指定したものにならないために、すでにproject.assets.jsonが存在した状態でビルドが正しく行えなくなっているのです。

### 解決方法
現状の解決方法は、ソリューションを分けることです。
project.assets.jsonのtargetに手動で両方とも書いてあげても解決するとは思いますが、なにせ自動生成されるファイルなので、書き換えを防止できないことを考えるとお勧めできません。