.NET Upgrade Assistantを試す
プロジェクト変換ツールの .NET Upgrade Assistant を使って、どのくらい上手く変換できるのか/できないのか、他にどんな事を考える必要があるかということを見ていきます。2月の投稿ですが内容は1月時点で確認したものです。
.NET Upgrade Assistant とは
Upgrade Assistantは.NET Frameworkプロジェクトを.NETプロジェクトに変換するのを助けてくれるツールです。 .NET 5まではWindowsデスクトップやASP.NETアプリケーションなどの変換が対象でしたが、.NET 6でXamarin.Android / iOSが.NETに統合されXamarin.Formsから.NET MAUIへの変換が追加されました。
.NET世代のツールらしく dotnet tool
コマンドでインストールできますが、Windows環境でしか動きません。
実際にファイル変更をともなう upgrade-assistant upgrade
、
変更が必要な箇所を分析する upgrade-assistant analyze
が利用できます。
詳しい使い方はGitHub上のドキュメントを参照してください。(dotnet/upgrade-assistant)
分析結果としてSARIFファイルが出力され、VS拡張を使うとVS 2022上で内容を見られるようです。(Microsoft SARIF Viewer 2022 - Visual Studio Marketplace)
このツールは必須なの?
必須ではありませんし、Upgrade Assistantを実行した後も手作業で修正が必要です。ある程度複雑なら新規に.NETプロジェクトを作って地道に移植するのが確実だと思います。
Xamarinからの改修ポイントを押さえるために、一度プロジェクトを変換してどのように変わるか見比べてみると参考になるでしょう。
Xamarin.Formsと.NET MAUIの対応
Xamarin.Xamarin.Android / iOSと.NET for Android / iOS、およびXamarin.Formsと.NET MAUIの対応関係は図のようになっています。
プロジェクトを変換してみる
サンプルプロジェクトとして、2023年1月のVS 2022で空のXamarin.Formsプロジェクトを新規作成した状態をベースに考えます。
- XFApp
- netstandard2.0プロジェクト。SDKスタイル。
- iOS、Androidプロジェクトから参照される。
- Modelsプロジェクトを参照している。
- Xamarin.FormsとXamarin.Essentialsをnugetパッケージで参照。
- XAML等が置かれる場所。
- XFApp.iOS
- Xamarin.iOSアプリケーションプロジェクト。
- Xamarin.FormsとXamarin.Essentialsをnugetパッケージで参照。
- XFApp.Android
- Xamarin.Androidアプリケーションプロジェクト。
- Xamarin.FormsとXamarin.Essentialsをnugetパッケージで参照。
- XFApp.Models
- netstandard2.0プロジェクト。SDKスタイル。
- Xamarin.Formsや他のプロジェクトに依存しないプロジェクト。
各プロジェクトの参照関係を図にすると次のようになります。
Upgrade Assistantはプロジェクト単位で変換・分析してくれるので、順番にかけてみましょう。
動かす
.slnファイルを指定して upgrade-assistant upgrade
コマンドを実行すると対話モードでツールが起動しました。実行環境にインストールされているdotnet SDKやVisual Studioを調べていることがわかります。おそらくこれらはアナライザーがコードを修正する際に使用されています。
ちなみに、この対話型コンソールで何も入力せずにEnterを押すと1番を選択したことになるようです。 基本的に1番で問題ありませんが、ステップ処理中にEnterを押すと次のコマンドが先行入力されてしまうので注意しましょう。
ソリューション内のプロジェクトが列挙されるので変換したいものを選択しましょう。
Xamarin.Forms非依存プロジェクト(.NET Standard)
まずはXamarin.Formsに依存していない.NET Standardプロジェクトから変換してみます。プロジェクト構成のXFApp.Modelsにあたります。
netstandard2.0からnet7.0(実行時の最新)プロジェクトに変換されて欲しいですが............、結果は何も変換されませんでした。 .NETプロジェクトから.NET Standardプロジェクトを参照することは問題ないため変換不要と判断されたようです。 他のプロジェクトと世代を合わせるために手動でcsproj内のTargetFrameworkを修正しておきましょう。
Xamarin.Formsプロジェクト(.NET Standard)
今度はXAMLやコードビハインドを置く用の.NET Standardプロジェクトを変換してみます。 プロジェクト構成のXFAppにあたります。
これから行う作業が列挙されます。
一通り適用すると以下のように変更されます。
- TargetFrameworksが netstandard2.0から
net7.0-android;net7.0-ios
のマルチターゲットプロジェクトになる。 - パッケージ参照がXamarin.Forms, Xamarin.EssentialsからMAUIに置き換わる。
- MAUI用のcsprojプロパティが設定される。(UseMaui)
- xamlやcsファイル中の名前空間がMAUIに置き換えられる。
- MAUIのテンプレートファイル(MauiProgram.cs)が追加される。
特に気になる部分についてコメントすると......
マルチターゲットプロジェクトに変わります。元がnetstandard2.0プロジェクトなので単純に更新するならnet7.0が順当なはずです。この結果はXamarin.FormsでいうとXamarin.iOS / Androidライブラリプロジェクト + Sharedプロジェクトに近いです。
変換前のユニットテストを活かすならターゲットをnet7.0を変更にした方が良さそうです。(このままではAndroid, iOSで動かさないとテストできない)
おそらくMauiImageなどの利用を想定してマルチターゲットプロジェクトになっている気がします。
Xamarin.Androidアプリプロジェクト
続いてAndroidプロジェクトです。プロジェクト構成のXFApp.Androidにあたります。
変換作業の内容はXamarin.Formsプロジェクトの時と同様なのでスクリーンショットは省略します。一通り適用すると以下のように変更されます。
- プロジェクトファイルがSDKスタイルに変更される。
- 暗黙的な設定やソースファイルの列挙が省略されるのでかなりスッキリします。Condition指定を利用していた場合は同様の結果になるか確認が必要だと思います。
- TargetFrameworksがnet7.0-androidになる。
- パッケージ参照がXamarin.FormsからMAUIに置き換わる。
- MAUI用のcsprojプロパティが設定される。(UseMaui)
- MAUIのテンプレートファイルが追加される。(MainApplication.cs)
- csファイル中の名前空間がMAUIに置き換えられる
- 型名のフルパス部分は変更されないため、空のXamarin.Formsプロジェクトからではどこも変更されませんでした。
画像リソースのMauiImage化などは起こりませんでした。
特に気になる部分についてコメントすると......
おそらくMainActivityが手つかずなので手動で改修しましょう。
- 基底クラスを FormsAppCompatActivity から MauiAppCompatActivity に変換。
- Xamarin.Forms向けの初期化処理を削除。
Platform.Init()
やForms.Init()
、LoadApplication()
などは不要です。
MainActivityに色々処理を追加していた場合は、基底クラスの実装と競合しないか念のため確認しておきましょう。
- maui/MauiAppCompatActivity.cs at main · dotnet/maui
- maui/MauiAppCompatActivity.Lifecycle.cs at main · dotnet/maui
Xamarin.iOSアプリプロジェクト
最後にiOSプロジェクトです。プロジェクト構成のXFApp.iOSにあたります。
変換作業の内容はXamarin.Formsプロジェクトの時と同様なのでスクリーンショットは省略します。一通り適用すると以下のように変更されます。
- プロジェクトファイルがSDKスタイルに変更される。
- 暗黙的な設定やソースファイルの列挙が省略されるのでかなりスッキリします。Condition指定を利用していた場合は同様の結果になるか確認が必要だと思います。
- TargetFrameworksがnet7.0-iosになる。
- パッケージ参照がXamarin.FormsからMAUIに置き換わる。
- MAUI用のcsprojプロパティが設定される。(UseMaui)
- MAUIのテンプレートファイルが追加される。
- はずなのですが実際には何も追加されません。
- AppDelegate.csを追加しようとするが、すでに同名ファイルが存在するため何もしないのだと思います。
- csファイル中の名前空間がMAUIに置き換えられる
AppDelegateの改修
まず基底クラスを FormsApplicationDelegate から MauiUIApplicationDelegate に変更します。 次に CreateMauiApp() の実装を追加します。Upgrade Assistantで追加されたMauiProgram.csに合わせると以下のようになります。
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
さいごに
プロジェクトファイルの変換、テンプレートファイルの追加、using部分の名前空間の変更はなかなか良い感じ処理してくれました。一方でXamarin.Forms、Xamarin.Essentials以外のライブラリは何もしてくれません。
特にXamarin.Formsに依存しているライブラリをどうするかというのが頭の痛い問題です。
MAUI版をリリースしてもらえない場合、フォークして作ることも検討しなければいけません。
Microsoft.Maui.Controls.Handlers.Compatibility
名前空間にはXamarin.FormsのRendererが移植されているため、そこに繋ぎこめば最低限の改修で動かせるようになると思います。(やって問題ないかはライブラリのライセンス形態によります)
フォローしませんか?
お気軽にご依頼・ご相談ください