.NET 8 リフレクションベースのシリアライゼーションに関する破壊的変更
.NET 8 リフレクションベースのシリアライゼーションに関する破壊的変更
概要
.NET 8では、PublishTrimmed
[1]プロジェクトでリフレクションベース[2]のシリアライゼーション[3][4]が自動的に無効化されるようになりました。この変更により、特定の条件下でシリアライゼーションが失敗することがあります。
変更内容の詳細
.NET 8以降、PublishTrimmed
プロパティが有効なプロジェクトでは、リフレクションベースのシリアライゼーションがデフォルトで無効になります。このプロパティが有効になっている場合、プロジェクトファイルで特に指定しない限り、次のコードは例外をスローします。
JsonSerializer.Serialize(new { Value = 42 });
このコードは、以下の例外をスローします。
System.InvalidOperationException: Reflection-based serialization has been disabled for this application.
変更理由
この変更は、ソースジェネレーターを使用し、安全でないリフレクションベースのコンポーネントへの依存を避けるためです。これにより、トリミングされたアプリケーションでの動作がより予測可能になり、ベストプラクティスの適用が促進されます。
推奨される操作
シリアライゼーションを正常に実行するためには、以下のいずれかの方法を採用することをお勧めします。
- ソースジェネレーターの使用: トリミングされたアプリケーションで安全かつ効率的にシリアライゼーションを行うために、ソースジェネレーターを使用します。
-
リフレクションベースのシリアライゼーションを有効にする: プロジェクトファイルで
JsonSerializerIsReflectionEnabledByDefault
プロパティを明示的に有効にします。
プロジェクトファイルの設定
プロジェクトファイル (.csproj) に以下の設定を追加して、リフレクションベースのシリアライゼーションを有効にします。
<PropertyGroup>
<PublishTrimmed>true</PublishTrimmed>
<JsonSerializerIsReflectionEnabledByDefault>true</JsonSerializerIsReflectionEnabledByDefault>
</PropertyGroup>
GPT-4による解説
PublishTrimmedのプロパティとは
「PublishTrimmed」というのは、.NETというプログラミングのツールで使われる設定の一つです。この設定を使うと、プログラムが軽く、速く動くようになります。
プロジェクトファイル (.csproj) に以下の設定をすることでオフにできます。
<PropertyGroup>
<PublishTrimmed>false</PublishTrimmed>
</PropertyGroup>
単一EXEファイルを作成するためのコマンドラインオプションにPublishTrimmedが含まれている場合があります。
dotnet publish -c Release -r win-x64 --self-contained true /p:PublishSingleFile=true /p:PublishTrimmed=false
コマンドオプションの説明
-
-c Release
: リリースモードでビルド -
-r win-x64
: ターゲットランタイムを指定 -
--self-contained true
: 自己完結型のEXEを作成 -
/p:PublishSingleFile=true
: 単一ファイルにパブリッシュ -
/p:PublishTrimmed=false
: トリミングを無効化
リフレクション
リフレクションとは、プログラムが実行時に自分自身の構造(クラスやメソッドなど)を調べたり変更したりする機能のことです。例えば、プログラムが自分で「このクラスにはどんなメソッドがあるのか」を確認するようなことです。
シリアライゼーション
シリアライゼーションとは、プログラムのデータを保存したり送信したりするために、データを一つの形式に変換することです。例えば、オブジェクト(プログラム内のデータ)をJSONやXMLなどの形式に変換することを指します。
リフレクションベースのシリアライゼーション
リフレクションベースのシリアライゼーションは、プログラムが実行時にリフレクションを使って、オブジェクトの構造を調べて、自動的にシリアライゼーションを行うことです。簡単に言うと、プログラムが「このオブジェクトにはこんなデータがあるから、こういう形式に変換しよう」と考えることです。
なぜ問題になるのか?
- .NET 8 以降の変更: .NET 8 以降では、プログラムを小さくして早く動かすために、不要な部分を取り除く「トリミング」が行われます。このとき、リフレクションを使ったシリアライゼーションはデフォルトで無効になります。
- エラーの原因: リフレクションベースのシリアライゼーションが無効になると、プログラムが自動的にデータの構造を調べてシリアライゼーションすることができなくなり、エラーが発生します。
解決策
- リフレクションベースのシリアライゼーションを有効にする: プロジェクト設定でリフレクションを使えるようにする。
- ソースジェネレーターを使う: プログラムの構造を事前に調べて、必要なシリアライゼーションコードを自動生成する方法です。
参考文献
(.NET 8の破壊的変更)PublishedTrimmed プロジェクトがリフレクション ベースのシリアル化に失敗する
-
「PublishTrimmed」というのは、.NETというプログラミングのツールで使われる設定の一つです。この設定を使うと、プログラムが軽く、速く動くようになります。 ↩︎
-
リフレクションとは、プログラムが実行時に自分自身の構造(クラスやメソッドなど)を調べたり変更したりする機能のことです。例えば、プログラムが自分で「このクラスにはどんなメソッドがあるのか」を確認するようなことです。 ↩︎
-
シリアライゼーションとは、プログラムのデータを保存したり送信したりするために、データを一つの形式に変換することです。例えば、オブジェクト(プログラム内のデータ)をJSONやXMLなどの形式に変換することを指します。 ↩︎
-
リフレクションベースのシリアライゼーションは、プログラムが実行時にリフレクションを使って、オブジェクトの構造を調べて、自動的にシリアライゼーションを行うことです。簡単に言うと、プログラムが「このオブジェクトにはこんなデータがあるから、こういう形式に変換しよう」と考えることです。 ↩︎
Discussion