MvvmCrossの概要

MvvmCrossは**Core**と**UI**で構成されています。

* Core
    * ViewModel、Service、Model、ビジネスロジック
    * .NET Standard library (バージョンが古い場合はPCLの可能性もあり・・）
* UI
    * View、Coreと**相互作用するための**プラットフォーム固有コード
    * ターゲットプラットフォームのネイティブプロジェクト

他にも、プロジェクトやアセンブリーを分けたりレイヤーを切り離して再使用性を向上したりすることもできます。

# MvvmCrossのキーオブジェクト(Key objects)

MvvmCrossのキーオブジェクトの構成はこのような感じになります（あくまでも僕の感覚です）

<img width="745" alt="fig" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202772/8b3ce6a5-1f69-8637-03e7-3f2aa0d956d1.png">

1. プラットフォームのアプリ立ち上げプロセスが走ります（エントリーポイント）
2. プラットフォームのアプリの構築中にUIパートの`Setup`オブジェクトが作成されます
3. `Setup.InitializePrimary`：メインスレッドの実行＋IoC、ロギングなどの初期化
4. `Setup.InitializeSecondary`：バックグラウンドスレッドの実行＋プラットフォームサービスの構築（バインディングなど）＋`App`オブジェクトの`Initialize`メソッドが呼ばれる＋最後にView/ViewModelの登録の検索を行う
5. `App.Initialize`が呼ばれると`AppStart`オブジェクトで最初のナビゲーションを決めさせる。`Setup`の最後ステップとして`AppStart.Startup(object hint)`が呼ばれる。
6. `AppStart.Startup(object hint)`が実行され、最初のViewModel/Viewが表示される

`hint`パラメータを使って、UIパートからCoreパートに初期化パラメータを送ることができます。
プッシュ通知の実装などに使えます。

|オブジェクト名|概要|Source Link|
|:-:|:--|:--|
|Setup|MvvmCrossアプリの構築|[MvxSetup.cs](https://github.com/MvvmCross/MvvmCross/blob/master/MvvmCross/Core/MvxSetup.cs)|
|App|Coreの初期化|[MvxApplication.cs](https://github.com/MvvmCross/MvvmCross/blob/master/MvvmCross/ViewModels/MvxApplication.cs)|
|AppStart|最初のViewModelの決定|[MvxAppStart](https://github.com/MvvmCross/MvvmCross/blob/master/MvvmCross/ViewModels/MvxAppStart.cs)|

# Core projectのクラスの詳細説明

## Appクラス

※`Application`(Android)や`ApplicationDelegate`(iOS)と混同しないように注意。

[MvxApplication.cs](https://github.com/MvvmCross/MvvmCross/blob/master/MvvmCross/ViewModels/MvxApplication.cs)

### `CreateDefaultViewModelLocator` メソッド
`IMvxViewModelLocator`を返却する。ここで何もオーバーライドしなければ`MvxDefaultViewModelLocator`が使われる。

### `LoadPlugins` メソッド
`IMvxPluginManager`を引数にとって（おそらく）プラグインがロードされるタイミングで呼ばれる。

### `Initialize` メソッド
バックグラウンドでの初期化をするときはここで行う。基本的にここに書くことになる。
ScaffoldやStarter Pack（今は無いらしい）を作成する時にすでに実装されている。

* `Service`と最後についたインターフェイスをシングルトンとして登録するように実装されている。
* `RegisterAppStart`で最初のViewModelを指定

### `Startup` メソッド
UIスレッドでの初期化をするときに`Task`を返却する。
`base`メソッドでログが取られているので特に必要がなければ`base`を呼ぶこと。

### `Reset` メソッド
アプリケーションがリスタートされたときに呼ばれる。
リスタートされる時はもう一度`Startup`メソッドも呼ばれるが、その前に呼ばれるようになっているらしいので初回起動でない場合を検知できる。
（ソースにはAndroidの最初のアクティビティはリスタートされると書いてあるが詳細は不明）

### `FindViewModelLocator` メソッド
`MvxViewModelRequest`を引数にとるが関係なしにデフォルトのロケータを探す。

### `RegisterAppStart`メソッド系
* `RegisterCustomAppStart<TMvxAppStart>`はカスタマイズした`AppStart`を型引数に指定する。
* `RegisterAppStart<TViewModel>`は型引数にViewModelを指定するとIoCに`MvxAppStart<TViewModel>`がシングルトンで登録される

```cs
Mvx.IoCProvider.ConstructAndRegisterSingleton<IMvxAppStart, MvxAppStart<TViewModel>>();
```

* `RegisterAppStart<TViewModel, TParameter>`はパラメータ付きで渡せる (`MvxAppStart<TViewModel, TParameter>`がIoCに登録される)

### `CreateableTypes()`メソッド系
* `CreatableTypes()` は返り値は`IEnumerable<Type>`　（通常Coreプロジェクトのアセンブリが入る）
* `CreatableTypes(Assembly)`は、アセンブリが指定できる

使用例は[Customizing App and Setup](https://www.mvvmcross.com/documentation/advanced/customizing-using-App-and-Setup)にて

### `MvxApplication<TParameter>`クラス
詳細不明
クラスの型パラメータは`TParameter`を返す`Startup`メソッドの引数の型になっている。

## ViewModel

* 変更を通知できるプロパティ
* コマンド
* 操作を管理するプライベートメソッド

ViewModelでできること

* リストを含める
* 他のViewModelへのナビゲーション
* 子のViewModelを含める
* IoCで構築する
* コンストラクタ、プロパティでのDI
* 定形コードを除くため`Fody.PropertyChanged`([Github](https://github.com/Fody/PropertyChanged))を使う

詳しくは別記事にて（工事中）

# Platform(UI) Projects

* ネイティブプラットフォームの初期コード
* カスタム`Setup.cs`
* `Views`
* カスタム`ViewPresenter`
* SDK依存コード

|プラットフォーム|ネイティブ|初期化|Setup|
|---|---|---|---|
|iOS|`AppDelegate`|[MvxApplicationDelegate.cs](https://github.com/MvvmCross/MvvmCross/blob/master/MvvmCross/Platforms/Ios/Core/MvxApplicationDelegate.cs)|[MvxIosSetup.cs](https://github.com/MvvmCross/MvvmCross/blob/master/MvvmCross/Platforms/Ios/Core/MvxIosSetup.cs)|
|macOS|`AppDelegate`|[MvxApplicationDelegate.cs](https://github.com/MvvmCross/MvvmCross/blob/master/MvvmCross/Platforms/Ios/Core/MvxApplicationDelegate.cs)|[MvxMacSetup.cs](https://github.com/MvvmCross/MvvmCross/blob/master/MvvmCross/Platforms/Mac/Core/MvxMacSetup.cs)|
|tvOS|`AppDelegate`|[MvxApplicationDelegate.cs](https://github.com/MvvmCross/MvvmCross/blob/master/MvvmCross/Platforms/Ios/Core/MvxApplicationDelegate.cs)|[MvxTvosSetup.cs](https://github.com/MvvmCross/MvvmCross/blob/master/MvvmCross/Platforms/Tvos/Core/MvxTvosSetup.cs)|
|Android|`Application`|[MvxAndroidApplication.cs](https://github.com/MvvmCross/MvvmCross/blob/master/MvvmCross/Platforms/Android/Views/MvxAndroidApplication.cs)|[MvxAndroidSetup.cs](https://github.com/MvvmCross/MvvmCross/blob/develop/MvvmCross/Platforms/Android/Core/MvxAndroidSetup.cs)|
|Android(Support)|`Application`|[MvxAppCompatApplication.cs](https://github.com/MvvmCross/MvvmCross/blob/4ab0a894372948194244e334d4e67dd3d85a0d6d/MvvmCross.DroidX/AppCompat/MvxAppCompatApplication.cs)#4ab0a89437|[MvxAppCompatSetup.cs](https://github.com/MvvmCross/MvvmCross/blob/4ab0a894372948194244e334d4e67dd3d85a0d6d/MvvmCross.DroidX/AppCompat/MvxAppCompatSetup.cs)#4ab0a89437|
|WPF|`App.xaml.cs`|MvxApplication.cs|[MvxWpfSetup.cs](https://github.com/MvvmCross/MvvmCross/blob/master/MvvmCross/Platforms/Wpf/Core/MvxWpfSetup.cs)|
|UWP|`App.xaml.cs`|MvxApplication.cs|[MvxWindowsSetup.cs](https://github.com/MvvmCross/MvvmCross/blob/master/MvvmCross/Platforms/Uap/Core/MvxWindowsSetup.cs)|

# Views

命名規則から、`View`の名前は`ViewModel`に関連付けられる

ジェネリクスで

```cs
public class MyView : MvxViewController<MyViewModel>
```
とすることもできる。

# View Presenters

ViewModelファーストなナビゲーションシステムの根本はView Presenterによるもの。そして、カスタマイズも高度にできる。

# 参考
* https://www.mvvmcross.com/documentation/getting-started/mvvmcross-overview