我々は MAUI で Goodbye Xamarin できるのか？

(この記事は多くの推測を含みます。[意見交換](https://blog.qiita.com/question-beta-release/) で投稿すると Advent Calendar とリンクできないので通常投稿します。)
[Xamarin は .NET6 の一部となる](https://devblogs.microsoft.com/dotnet/introducing-net-multi-platform-app-ui/) ことが発表されて半年程度が経過しました。
既存の、あるいはこれからスクラッチする Xamarin 製アプリは .NET6 および MAUI リリースによる影響を把握しておく必要があります。
[.NET6 のリリースは 2021年11月予定](https://github.com/dotnet/core/blob/master/roadmap.md)とのことですから、猶予はあと1年間ですね。
今年は .NET/Xamarin の情報をあまりキャッチアップできていないので、復習も兼ねて、 **既存の Xamarin 製アプリを .NET6/MAUI にマイグレーションするために必要な具体的な作業は何か？** について情報収集してみました。

## MAUI発表当時に思っていたこと

MAUI が発表されたとき、「あー "Xamarin" という固有名詞は無くなって、ライブラリ名や namespace/class名 からも消えてゆくのだな」と考えていました。

### 私の予想構成図

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8227/3f28f015-4ae6-d052-0d47-852b549501a5.png)

### 私の予想コード

#### .NET5/Xamarin.Forms 現在

```csharp
// X-plat
var button = new Xamarin.Forms.Button();
button.click += (s, e) => { /* clicked */ };

// Android specific
var nativeButton = new global::Android.Widget.Button();
nativeButton.click += (s, e) => { /* clicked */ };
```

#### .NET6/MAUI 以降

```csharp
// X-plat
var button = new System.Maui.Button();
button.click += (s, e) => { /* clicked */ };

// Android specific
var nativeButton = new global::Android.Widget.Button();
nativeButton.click += (s, e) => { /* clicked */ };
```

ところが情報収集しているうちに「Xamarin という固有名詞はホントに(完全に)なくなるのか？」と疑念が生じてきました。

## 現状把握

2020年12月現在、公式に近い最新情報は David Ortinau 氏のこちらの発表動画(2020年10月にオンライン開催されたコミュニティイベント)かなと思いましたので、こちらを観て現在の予定を理解してみました。

- [David Ortinau - Introducing .NET MAUI - XamExpertDay 2020 - YouTube](https://www.youtube.com/watch?v=qbHO8J3bId0)

## 動画で気になったところ

### xamarin/android は dotnet/android になる？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8227/eaad2fcb-6d96-291d-7dff-bb26e3958609.png)

まずはこちら。
Xamarin の integrate 先として

- github.com/dotnet/maui
- github.com/dotnet/android
- github.com/dotnet/macios

が示されていますが、現在 /maui 以外のリポジトリはありません(公開されていません？)。
これは現在の [github.com/xamarin/xamarin-android](https://github.com/xamarin/xamarin-android) が、github.com/dotnet/android に移動することを示しているのでしょうか？

### UI定義はあまり変わらなさそう

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8227/de228479-40dc-ceb6-5262-b8eda19228b0.png)

特に XAML は、もともと Xamarin 成分は少なかったので、ほぼそのまま使えそうな気がします。
コードでの定義も、namespace は分かりませんが実質のコードは変わらないのでしょう。

※MAUI では XAML の他に、MVU や ReactiveUI, Blazor も使用可になるとのことですが、ここではそれらは割愛します。

### カスタムレンダラーの作り方は変わりそう

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8227/a0544745-3faa-9a22-46f4-2b14e64482b6.png)

共通UI部品からそれぞれのネイティブUI部品にバインドするのは MAUI でも変わりませんが、その仕組みは Xamarin.Forms から変更があるようです。
Xamarin.Forms では Control と Renderer を実装していましたが、それに加え Handler と Mapper という概念が必要になるようです。

### MAUI の位置づけがよく分からなくなってきた汗

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8227/c9b5ea3d-4faa-cb1c-0f8a-261025e8906f.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8227/4861c223-8eba-f4a8-2461-f1733234f5d5.png)

「Xamarin.Forms から Renderer を分離して、さらに汎化させる」のような事を言っているのだと思いますが、MAUI の ``IButton`` の実装として、Xamarin.Forms があり、Comet([MVUでの実装と思われ](https://github.com/Clancey/Comet)) や ReactiveButton があり…、と「Xamarin.Forms すらもその上位から使用される立場」であることが示唆されています。

であるならば、Xamarin.Forms は「MAUI の選択肢のひとつ」として残る、つまり Uno Platform や Mobile Blazor Bindings と同レベルの概念として在り続ける、ということになります。 

- [unoplatform/Uno.Xamarin.Forms.Platform: Uno Platform WebAssembly Renderers for Xamarin.Forms](https://github.com/unoplatform/Uno.Xamarin.Forms.Platform)
- [Mobile Blazor Bindings は「Xamarin.Forms アプリ生成器」でした - Qiita](https://qiita.com/amay077/items/2b0d0d903ce3b1d8410d)

あれ？ ``IButton`` は ``System.Maui.IButton`` になると考えると、``Xamarin.Forms.Button`` は、どんな namespace+class になるのだろう？

「共通インターフェースとしての MAUI」と「実装の一つとしての MAUI」が存在するのでしょうか？。。。

ちなみに [dotnet/maui の repo](https://github.com/dotnet/maui/blob/174e61449695c5fe584a7e38fbc589cb5745a18a/src/Platform.Renderers/src/Xamarin.Forms.Platform.Android/Renderers/BoxRenderer.cs) には、現状 ``Platform.Renderers/src/Xamarin.Forms.Platform.Android/Renderers/XXXRenderer`` という構成になっているので、このままリリースされたら、(公開APIかは置いといて) Xamarin という名称は残る事になります。

### 現行 Xamarin.Forms との互換性は保たれるっぽい…ということは？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8227/23c8cda1-dfc5-546b-c58b-a1184f91e7dc.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8227/da53d56c-b7bc-2df4-6f80-b79de492cc53.png)

- 既存の CustomRenderer は書き換える必要があるか？ → No
- サードパーティ製の Xamarin.Forms 向けUI部品はそのまま使えるか？ → Yes(ターゲット変更してビルドすれば)

との事なので、既存アプリの部品は MAUI でも動くようです。
ということは、.NET6 では Breaking Changes は無いのでしょうか？そんな事ないよね?何らかの Wrapper が用意されるのでしょうか？

## その他の情報

[Feature Roadmap · xamarin/Xamarin.Forms Wiki](https://github.com/xamarin/Xamarin.Forms/wiki/Feature-Roadmap) には、以下の記述があります。

> Transition to .NET MAUI
July 15, 2020 Pull Request Policy Changes
As noted below, Xamarin.Forms 5.0 is due out at the end of September. At that time we will re-sync dotnet/maui and work on preparing our first preview release of .NET MAUI. In order to be considered for release by or before Xamarin.Forms 5.0, feature pull requests should be submitted for review by July 15.
> 
> After July 15, any new feature pull requests may still be submitted to this repository (xamarin/xamarin.forms). We will label those for migration to dotnet/maui. Be aware that the bulk of renderer refactoring will happen after Xamarin.Forms 5.0, so contributions to controls and renderers may require refactoring.
> 
> Pull requests to fix issues will continue to be reviewed through November 2022, and sync'd with dotnet/maui using a combination of automation and manual implementation.
> 
> Have an exception? These plans and dates are to help us make a smooth transition to release .NET MAUI with .NET 6 in November 2021. If you feel you have a need that should be an exception to this, shoot a message to Program Manager, David Ortinau. david.ortinau@microsoft.com.

意訳すると、

- Xamarin.Form 5.0 がリリースされたら MAUI への移行に取りかかるよ
- なので PR には dotnet/maui への移行用のラベルを付けるよ
- 2022年11月まではこの repo でも PR を受け付けるよ

とのことなので、Xamarin.Form repo は MAUI のリリース時には dotnet/maui への最初の移行が完了していると思われます。
ちなみに現在 maui と名の付いたラベルやブランチは見つかりませんでした。

## まとめ

いかがでしたか？
いろいろ調べてみましたが「既存の Xamarin 製アプリを .NET6/MAUI にマイグレーションするために必要な具体的な作業」はよく分かりませんでした。

で締めたら怒られそうですが、

- リリースまで1年間も無いこと
- MAUI とは Xamarin.Forms のさらに上位層なのか？ということ
- 既存のカスタムレンダラーや 3rd party 製ライブラリは使えること

などを考えると、多くの Breaking Changes は無いのではないかなーと予想します。
とりあえず現状でできることは、「Xamarin に非依存なコードは別プロジェクトにして MAUI でも再利用可能にしておく」くらいでしょうかね。