.Net6が出たのでMAUIをチェックする

# .Net6リリース

2021/11/08に出たようです。
というのは[全ダウンロードのページ](https://dotnet.microsoft.com/download/dotnet/6.0)から。
というわけで、さらっと見ていきましょう。

## インストール

※下記は何も考えずにやってしまいましたが、**正しくは[こちら](https://github.com/dotnet/maui/blob/main/.github/DEVELOPMENT.md)を参考に行ってください**

### macOS

.Net6は[ダウンロードページ](https://dotnet.microsoft.com/download)から。
インストールしてworkloadの一覧を出してみましたが、mauiしか入っていませんでした。

```shell
$ dotnet workload list
.NET 6.0 へようこそ!
---------------------
SDK バージョン: 6.0.100

--snip--

インストール済みワークロード ID
-----------------
maui             
```

これはあれですね。
previewの頃の名残ですね。

[maui-check](https://github.com/Redth/dotnet-maui-check)を使用して全部入りにします。

```shell
$ maui-check
      _   _   _____   _____     __  __      _      _   _   ___                                                                                              
     | \ | | | ____| |_   _|   |  \/  |    / \    | | | | |_ _|                                                                                             
     |  \| | |  _|     | |     | |\/| |   / _ \   | | | |  | |                                                                                              
  _  | |\  | | |___    | |     | |  | |  / ___ \  | |_| |  | |                                                                                              
 (_) |_| \_| |_____|   |_|     |_|  |_| /_/   \_\  \___/  |___|                                                                                             
                                                                                                                                                            
🚑 .NET MAUI Check v0.10.0.0 💉

--snip--

🔎 .NET SDK - Workloads (6.0.100) Checkup...
  ✔ android-aot (Microsoft.NET.Sdk.Android.Manifest-6.0.100 : 31.0.101-preview.10.59) installed.
  ✔ ios (Microsoft.NET.Sdk.iOS.Manifest-6.0.100 : 15.0.101-preview.10.251) installed.
  ✔ maccatalyst (Microsoft.NET.Sdk.MacCatalyst.Manifest-6.0.100 : 15.0.101-preview.10.251) installed.
  ✔ tvos (Microsoft.NET.Sdk.tvOS.Manifest-6.0.100 : 15.0.101-preview.10.251) installed.
  ✔ macos (Microsoft.NET.Sdk.macOS.Manifest-6.0.100 : 12.0.101-preview.10.251) installed.
  ✔ maui (Microsoft.NET.Sdk.Maui.Manifest-6.0.100 : 6.0.101-preview.10.2068) installed.
  ✔ wasm-tools (microsoft.net.workload.mono.toolchain.manifest-6.0.100 : 6.0.0) installed.
  ✔ microsoft-net-sdk-emscripten (microsoft.net.workload.emscripten.manifest-6.0.100 : 6.0.0) installed.
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

--snip--

$ dotnet --version
6.0.100

$ dotnet new --list
これらのテンプレートは、入力:  と一致しました

テンプレート名                         短い名前                 言語          タグ                                                                                        
------------------------------  -------------------  ----------  ------------------------------------------------------------------------------------------
.NET MAUI App (Preview)         maui                 [C#]        MAUI/Android/iOS/macOS/Mac Catalyst/WinUI                                                 
.NET MAUI Blazor App (Preview)  maui-blazor          [C#]        MAUI/Android/iOS/macOS/Mac Catalyst/WinUI/Blazor                                          
.NET MAUI Class Library (Pr...  mauilib              [C#]        MAUI/Android/iOS/macOS/Mac Catalyst/WinUI                                                 
.NET MAUI ContentPage (C#) ...  maui-page-csharp     [C#]        MAUI/Android/iOS/macOS/Mac Catalyst/WinUI/Xaml/Code                                       
.NET MAUI ContentPage (Prev...  maui-page-xaml       [C#]        MAUI/Android/iOS/macOS/Mac Catalyst/WinUI/Xaml/Code                                       
.NET MAUI ContentView (C#) ...  maui-view-csharp     [C#]        MAUI/Android/iOS/macOS/Mac Catalyst/WinUI/Xaml/Code                                       
.NET MAUI ContentView (Prev...  maui-view-xaml       [C#]        MAUI/Android/iOS/macOS/Mac Catalyst/WinUI/Xaml/Code                                       

--snip--
```


### windows

こちらも.Net6は[ダウンロードページ](https://dotnet.microsoft.com/download)から。
インストールしてworkloadの一覧を出してみましたが、何も入っていませんでした。
先日色々あってWindows自体を入れ直しましたので…。

```shell
> dotnet workload list

このコマンドは、本バージョンの SDK で `dotnet ワークロード インストール` を介してインストールされたワークロードのみを表
示し、Visual Studio を介してインストールされたワークロードは表示しません。

インストール済みワークロード ID
-----------------
```

こちらも`maui-check`でworkloadをインストール。
すると、Visual Studioのチェックでダメ出しが。

```text
? Visual Studio 17.1.0-pre.1.0 Checkup...
  ? 16.11.5
  ? 17.0.0
  × Missing Visual Studio >= 17.1.0-pre.1.0
```

Visual Studio 2022 Current が出てたので入れ、previewを消したのがまずかったようです。
入れてから再度やってみると、

```text
? Visual Studio 17.1.0-pre.1.0 Checkup...
  ? 16.11.5
  ? 17.0.0
  ? 17.1.0-pre.1.0 - C:\Program Files\Microsoft Visual Studio\2022\Preview
```

問題ないですね。

```shell
> dotnet workload list

このコマンドは、本バージョンの SDK で `dotnet ワークロード インストール` を介してインストールされたワークロードのみを表
示し、Visual Studio を介してインストールされたワークロードは表示しません。

インストール済みワークロード ID
-----------------
```

あれ？入ってませんね。


### Linux

使用したディストリビューションはRockyLinux。
CentOS後継というアレです。
パッケージマネージャ使って（[参考](https://docs.microsoft.com/ja-jp/dotnet/core/install/linux-centos#centos-8-)）インストールです。

```text
$ sudo dnf install dotnet-sdk-6.0
依存関係が解決しました。
=============================================================================================================================================================
 パッケージ                                    アーキテクチャー      バージョン                             リポジトリー                               サイズ
=============================================================================================================================================================
インストール:
 dotnet-sdk-6.0                                x86_64                6.0.100-1                              packages-microsoft-com-prod                114 M
依存関係のインストール:
 aspnetcore-runtime-6.0                        x86_64                6.0.0-1                                packages-microsoft-com-prod                8.7 M
 aspnetcore-targeting-pack-6.0                 x86_64                6.0.0-1                                packages-microsoft-com-prod                2.0 M
 dotnet-apphost-pack-6.0                       x86_64                6.0.0-1                                packages-microsoft-com-prod                4.7 M
 dotnet-host                                   x86_64                6.0.0-1                                packages-microsoft-com-prod                 67 k
 dotnet-hostfxr-6.0                            x86_64                6.0.0-1                                packages-microsoft-com-prod                173 k
 dotnet-runtime-6.0                            x86_64                6.0.0-1                                packages-microsoft-com-prod                 29 M
 dotnet-runtime-deps-6.0                       x86_64                6.0.0-1                                packages-microsoft-com-prod                3.9 k
 dotnet-targeting-pack-6.0                     x86_64                6.0.0-1                                packages-microsoft-com-prod                3.1 M
 netstandard-targeting-pack-2.1                x86_64                5.0.208-1.el8_4.rocky.0                appstream                                  1.5 M

--snip--

インストール済み:
  aspnetcore-runtime-6.0-6.0.0-1.x86_64                           aspnetcore-targeting-pack-6.0-6.0.0-1.x86_64   dotnet-apphost-pack-6.0-6.0.0-1.x86_64    
  dotnet-host-6.0.0-1.x86_64                                      dotnet-hostfxr-6.0-6.0.0-1.x86_64              dotnet-runtime-6.0-6.0.0-1.x86_64         
  dotnet-runtime-deps-6.0-6.0.0-1.x86_64                          dotnet-sdk-6.0-6.0.100-1.x86_64                dotnet-targeting-pack-6.0-6.0.0-1.x86_64  
  netstandard-targeting-pack-2.1-5.0.208-1.el8_4.rocky.0.x86_64  

完了しました!

$ dotnet --version
6.0.100

$ dotnet workload list

インストール済みワークロード ID
-----------------
```

jdkをインストールして、

```shell
$ sudo dnf install java-11-openjdk java-11-openjdk-devel
$ echo 'export JAVA_HOME=$(dirname $(dirname $(readlink $(readlink $(which javac)))))' >> ~/.bash_profile
$ echo 'export PATH=$PATH:$JAVA_HOME/bin' >> ~/.bash_profile
```

maui-checkを動かします。

```text
🔔 Attempt to fix? [y/n] (y): y
⏳ Attempting to fix: .NET SDK - Workloads (6.0.100)
SHELL: /bin/bash /tmp/tmpEXZkrS.tmp
[sudo] xxxx のパスワード:
ワークロード ID ios は、このプラットフォームでサポートされていません。
Fix failed - Workload Install failed: `dotnet workload install --from-rollback-file "/tmp/maui-check-a795017a/workload.json" android-aot ios maccatalyst tvos macos maui wasm-tools --source "https://api.nuget.org/v3/index.json"`
```

なるほど残念。
ではmacOS/iOS関連をはずして…。

```shell
$ sudo `which dotnet` workload install --from-rollback-file "/tmp/maui-check-a795017a/workload.json" android-aot maui wasm-tools --source "https://api.nuget.org/v3/index.json"
ワークロード ID maui は、このプラットフォームでサポートされていません。
```

ああ、残念…。
workload個別では。

```shell
$ dotnet workload search

ワークロード ID         説明                                                                   
---------------------------------------------------------------------------------------
android           .NET SDK Workload for building Android applications.                 
android-aot       .NET SDK Workload for building Android applications with AOT support.
macos             .NET SDK Workload for building macOS applications.                   
maui-android      .NET MAUI SDK for Android                                            
maui-windows      .NET MAUI SDK for Windows                                            
wasm-tools        .NET WebAssembly ビルド　ツール                                             

$ sudo `which dotnet` workload install android

--snip--

Pack Microsoft.Android.Sdk バージョン 31.0.101-preview.10.59 をインストールしています...
ワークロードをインストールできませんでした。インストール パックをロールバックしています...
パック Microsoft.Android.Sdk のインストールをロールバックしています...
ワークロード microsoft.android.sdk.linux::31.0.101-preview.10.59 が NuGet フィード https://api.nuget.org/v3/index.json" に見つかりません。 をインストールできませんでした

$ sudo `which dotnet` workload install maui-windows wasm-tools

--snip--

ワークロード maui-windows wasm-tools が正常にインストールされました。

$ dotnet workload list

インストール済みワークロード ID
-----------------
maui-windows     
wasm-tools       

$ dotnet new --list
これらのテンプレートは、入力:  と一致しました

テンプレート名                                       短い名前              言語          タグ                                                 
--------------------------------------------  ----------------  ----------  ---------------------------------------------------
.NET MAUI App (Preview)                       maui              [C#]        MAUI/Android/iOS/macOS/Mac Catalyst/WinUI          
.NET MAUI Blazor App (Preview)                maui-blazor       [C#]        MAUI/Android/iOS/macOS/Mac Catalyst/WinUI/Blazor   
.NET MAUI Class Library (Preview)             mauilib           [C#]        MAUI/Android/iOS/macOS/Mac Catalyst/WinUI          
.NET MAUI ContentPage (C#) (Preview)          maui-page-csharp  [C#]        MAUI/Android/iOS/macOS/Mac Catalyst/WinUI/Xaml/Code
.NET MAUI ContentPage (Preview)               maui-page-xaml    [C#]        MAUI/Android/iOS/macOS/Mac Catalyst/WinUI/Xaml/Code
.NET MAUI ContentView (C#) (Preview)          maui-view-csharp  [C#]        MAUI/Android/iOS/macOS/Mac Catalyst/WinUI/Xaml/Code
.NET MAUI ContentView (Preview)               maui-view-xaml    [C#]        MAUI/Android/iOS/macOS/Mac Catalyst/WinUI/Xaml/Code
```

とりあえず、テンプレートが使えるところまでは確認。
なお、Ubuntuはwslを使って試しましたが、パッケージマネージャが`dnf`→`apt`になるだけで変わりませんでした。

## プロジェクトを作って色々みてみる

```shell
$ dotnet new maui -n MauiTest
$ ce MauiTest
$ code .
```

見ていきましょう。

### プロジェクトが１つになっている

preview4の時には android/ios/maccatalyst と windows とで２つのプロジェクトができていましたが、preview6あたりから１つになるように設計し直しているようです。
そして、各プラットフォーム用は `Platforms` 内にまとまっています。

```shell
$ find . -type d
.
./MauiTest
./MauiTest/obj
./MauiTest/obj/Debug
./MauiTest/obj/Debug/net6.0-android
./MauiTest/obj/Debug/net6.0-android/designtime
./MauiTest/obj/Debug/net6.0-android/stamp
./MauiTest/Platforms
./MauiTest/Platforms/Android
./MauiTest/Platforms/Android/Resources
./MauiTest/Platforms/Android/Resources/values
./MauiTest/Platforms/iOS
./MauiTest/Platforms/iOS/Resources
./MauiTest/Platforms/MacCatalyst
./MauiTest/Platforms/Windows
./MauiTest/Properties
./MauiTest/Resources
./MauiTest/Resources/Fonts
./MauiTest/Resources/Images
```

### Windowsでビルドできない

```shell
$ dotnet build -f net6.0-windows10.0.19041
.NET 向け Microsoft (R) Build Engine バージョン 17.0.0+c9eb9dd64
Copyright (C) Microsoft Corporation.All rights reserved.

  復元対象のプロジェクトを決定しています...
  C:\Projects\MauiCheck\MauiCheck.csproj を復元しました (19.37 sec)。
C:\.nuget\packages\microsoft.windows.sdk.buildtools\10.0.20348.19\build\Microsoft.Windows.SDK.BuildTools.props(4,37): error MSB4185: 型 "System.Environment" の関数 "Is64BitProcess" を MSBuild プロパティ関数として実行することは できません。 [C:\Projects\MauiCheck\MauiCheck.csproj]

ビルドに失敗しました。
```

ということで。
深くは調査していませんが、何かあるのかもしれないですね｀

### iOSのエミュレーターの種類を指定する

[ここ](https://github.com/dotnet/maui/wiki/CLI:-iOS-Simulator-Selection)に書いてあります。
`simctl`は初回に起動時に何かインストールを行います。

```
$ /Applications/Xcode.app/Contents/Developer/usr/bin/simctl
Install Started
1%.........20.........40.........60.........80......Install Succeeded

--snip--

$ /Applications/Xcode.app/Contents/Developer/usr/bin/simctl list
2021-11-10 08:42:03.503 simctl[13963:614466] CoreSimulator detected version change.  Framework version (776.4) does not match existing job version (776.3).  Attempting to remove the stale service in order to add the expected version.
== Device Types ==
iPhone 4s (com.apple.CoreSimulator.SimDeviceType.iPhone-4s)
iPhone 5 (com.apple.CoreSimulator.SimDeviceType.iPhone-5)
iPhone 5s (com.apple.CoreSimulator.SimDeviceType.iPhone-5s)
iPhone 6 Plus (com.apple.CoreSimulator.SimDeviceType.iPhone-6-Plus)
iPhone 6 (com.apple.CoreSimulator.SimDeviceType.iPhone-6)
iPhone 6s (com.apple.CoreSimulator.SimDeviceType.iPhone-6s)
iPhone 6s Plus (com.apple.CoreSimulator.SimDeviceType.iPhone-6s-Plus)
iPhone SE (1st generation) (com.apple.CoreSimulator.SimDeviceType.iPhone-SE)

--snip--

Apple Watch Series 7 - 41mm (com.apple.CoreSimulator.SimDeviceType.Apple-Watch-Series-7-41mm)
Apple Watch Series 7 - 45mm (com.apple.CoreSimulator.SimDeviceType.Apple-Watch-Series-7-45mm)
== Runtimes ==
iOS 13.3 (13.3 - 17C45) - com.apple.CoreSimulator.SimRuntime.iOS-13-3
iOS 14.4 (14.4 - 18D46) - com.apple.CoreSimulator.SimRuntime.iOS-14-4
iOS 15.0 (15.0 - 19A339) - com.apple.CoreSimulator.SimRuntime.iOS-15-0
tvOS 15.0 (15.0 - 19J344) - com.apple.CoreSimulator.SimRuntime.tvOS-15-0
watchOS 8.0 (8.0 - 19R345) - com.apple.CoreSimulator.SimRuntime.watchOS-8-0
== Devices ==
-- iOS 13.3 --
    iPhone 8 (F1187E4E-4EBE-44B6-B6EB-A6B73044F73F) (Shutdown) 
    iPhone 8 Plus (DBF5823E-55D1-41FC-BAD6-257C8275C2B2) (Shutdown) 
    iPhone 11 (8A0FBFC3-77D4-4B3D-9BFA-782831F2E009) (Shutdown) 
    iPhone 11 Pro (256EE6EB-A8F1-4E1D-9026-AB57D29F04CB) (Shutdown) 
    iPhone 11 Pro Max (E937B959-3839-4A91-A321-4A9F573891E4) (Shutdown) 
    iPad Pro (9.7-inch) (C8BF76C2-66F2-46CA-AB1D-BB44ACF2627A) (Shutdown) 
    iPad (7th generation) (6EFEBDE3-9F4B-4002-8B5D-76C30D62E128) (Shutdown) 
    iPad Pro (11-inch) (1st generation) (25C09123-E55D-4DB4-B112-4C45AB6173FD) (Shutdown) 
    iPad Pro (12.9-inch) (3rd generation) (17958345-D47A-4E6F-A9FF-C5E047C40642) (Shutdown) 
    iPad Air (3rd generation) (DBF213FA-4DEE-4DF6-81EA-4640407A881E) (Shutdown) 
-- iOS 14.4 --
    iPhone 8 (122ADCC4-590E-4657-AAC1-EB013C2B0A04) (Shutdown) 
    iPhone 8 Plus (52467253-E8EE-449F-995B-5FD32A11D733) (Shutdown) 
    iPhone 11 (1BBF1C65-CB2D-4DE4-A15F-F91CC1A5FB01) (Shutdown) 

--snip--
```

この一覧内のDevicesの中のUDIDを下記のように指定して実行できます。

```
$ dotnet build -f net6.0-ios -t:Run -p:_DeviceName=:v2:udid=122ADCC4-590E-4657-AAC1-EB013C2B0A04
.NET 向け Microsoft (R) Build Engine バージョン 17.0.0+c9eb9dd64
Copyright (C) Microsoft Corporation.All rights reserved.

  復元対象のプロジェクトを決定しています...
  復元対象のすべてのプロジェクトは最新です。
  Detected signing identity:
          
    Bundle Id: com.companyname.MauiTest
    App Id: com.companyname.MauiTest
  MauiTest -> /Volumes/Datas/home2/tomita/Projects/MauiTest/MauiTest/bin/Debug/net6.0-ios/iossimulator-x64/MauiTest.dll
  アセンブリのサイズを最適化しています。これにより、アプリの動作が変更される可能性があります。公開した後にテストしてください。https://aka.ms/dotnet-illink を参照してください
```

上記の場合、iPhone8 iOS14.4 のエミュレーターが起動し、ビルドされたアプリがエミュレーター内で起動されます。

### DIのこと

MAUIには最初から依存性注入の機能があります。
具体的には、`MauiProgram.cs`で以下のように定義し、

```csharp
using Microsoft.Extensions.DependencyInjection;

namespace MauiTest
{
	public static class MauiProgram
	{
		public static MauiApp CreateMauiApp()
		{
			var builder = MauiApp.CreateBuilder();
			builder
                .UseMauiApp<App>()
				.ConfigureFonts(fonts =>
				{
					fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
				});

			builder.Services.AddSingleton<TestObject>();

			return builder.Build();
		}

		public static IServiceProvider Services
		{
			get
			{
#if WINDOWS10_0_17763_0_OR_GREATER
				return MauiWinUIApplication.Current.Services;
#elif ANDROID
				return MauiApplication.Current.Services;
#elif IOS || MACCATALYST
				return MauiUIApplicationDelegate.Current.Services;
#else
				return null;
#endif
			}
		}
	}
}
```

`builder.Services.AddSingleton`等で定義したものを使用するには、

```csharp
var testObject = MauiProgram.Services.GetService<TestObject>();
```

で取得できます。
（[MAUIのサンプル、WeatherTwentyOne](https://github.com/davidortinau/WeatherTwentyOne/blob/67909ee54d0da0c3178a85b552da2af1b2f1f25f/src/WeatherTwentyOne/Services/ServiceExtensions.cs#L3)より）