Prism コードサンプル学習：07-Modules

# Prism コードサンプル学習：07-Modules

## はじめに

以下の記事の続きです。
<https://qiita.com/mngreen/items/41d3bd3159be3b279a5f>

## 07-Modules

本サンプルではModuleの読み込みを、以下の5パターンの方法で行うやり方です。

- App.configを用いた読み込み[07-Modules - AppConfig](https://github.com/PrismLibrary/Prism-Samples-Wpf/tree/master/07-Modules%20-%20AppConfig)
- プロジェクトを参照し、IModuleCatalogを用いて読み込み[07-Modules - Code](https://github.com/PrismLibrary/Prism-Samples-Wpf/tree/master/07-Modules%20-%20Code)
- Moduleが格納されているフォルダを指定して読み込み[07-Modules - Directory](https://github.com/PrismLibrary/Prism-Samples-Wpf/tree/master/07-Modules%20-%20Directory)
- ModuleInfoのインスタンスを生成してIModuleCatalogに追加[07-Modules - LoadManual](https://github.com/PrismLibrary/Prism-Samples-Wpf/tree/master/07-Modules%20-%20LoadManual)
- ModuleInfoをXamlで定義し、そのXaml構造からModuleCatalogを生成[07-Modules - Xaml](https://github.com/PrismLibrary/Prism-Samples-Wpf/tree/master/07-Modules%20-%20Xaml)

### App.configを用いた読み込み

- App.configで読み込まれるようにどこで設定されているか
  - App.xaml.csでCreateModuleCatalogをオーバーライドして

    ```csharp
     return new ConfigurationModuleCatalog();
    ```

    としているが、この内部の呼び先をたどっていくと[ConfigurationStore.Desktop](https://github.com/PrismLibrary/Prism/blob/f8230bfb6fb875b3717b915a69c567d8dc9a3a46/src/Wpf/Prism.Wpf/Modularity/ConfigurationStore.Desktop.cs#L16)に到達する。App.configが参照されるのは、ここで[ConfigurationManager](https://docs.microsoft.com/ja-jp/dotnet/api/system.configuration.configurationmanager?view=dotnet-plat-ext-5.0)を利用しているから。

### プロジェクトを参照し、IModuleCatalogを用いて読み込み

- 呼び出されているメソッドは[ここ](https://github.com/PrismLibrary/Prism/blob/f8230bfb6fb875b3717b915a69c567d8dc9a3a46/src/Wpf/Prism.Wpf/Modularity/IModuleCatalogExtensions.cs#L128)。
  - このメソッドを呼び出すと型情報からModuleCatalogを生成して追加してくれる。最終的に呼び出されるのは[ここ](https://github.com/PrismLibrary/Prism/blob/f8230bfb6fb875b3717b915a69c567d8dc9a3a46/src/Wpf/Prism.Wpf/Modularity/IModuleCatalogExtensions.cs#L151l)のはず。

### Moduleが格納されているフォルダを指定して読み込み

- フォルダパスを指定すると、それ以下のModuleをかき集めてくれる。実際に読み込み処理が発生するのは[ここ](https://github.com/PrismLibrary/Prism/blob/f8230bfb6fb875b3717b915a69c567d8dc9a3a46/src/Wpf/Prism.Wpf/Modularity/DirectoryModuleCatalog.netcore.cs#L78)
  - 内部で使用されているイベントは[遅延ローディングする仕組み](https://qiita.com/mngreen/items/ce65e306bdcc4ea2382b)で見たのと同じように見える。
- ビルド時にModuleフォルダに格納するように設定の変更が必要

### ModuleInfoのインスタンスを生成してIModuleCatalogに追加

- [プロジェクトを参照し、IModuleCatalogを用いて読み込み](#プロジェクトを参照し、IModuleCatalogを用いて読み込み)が隠蔽しているところを自前でもできることを示しているだけ。

### ModuleInfoをXamlで定義し、そのXamlからModuleCatalogを生成

- Uriでxamlを指定し、dllを読み込む。[処理はここ](https://github.com/PrismLibrary/Prism/blob/v7.2.0.1422/Source/Wpf/Prism.Wpf/Modularity/ModuleCatalog.cs#L64)
  - 以下のように読み込み対象のモジュールを指定する。

    ```xml
    <m:ModuleCatalog xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:m="clr-namespace:Prism.Modularity;assembly=Prism.Wpf">

    <m:ModuleInfo ModuleName="ModuleAModule" 
                  ModuleType="ModuleA.ModuleAModule, ModuleA, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />

    </m:ModuleCatalog>
    ```

## 個人的所感

- プロジェクト参照が必要な方法は以下。
  - プロジェクトを参照し、IModuleCatalogを用いて読み込み
  - ModuleInfoのインスタンスを生成してIModuleCatalogに追加
- プロジェクト参照がなくても動的に読み込める方法は以下。
  - App.configを用いた読み込み
  - Moduleが格納されているフォルダを指定して読み込み
  - ModuleInfoをXamlで定義し、そのXamlからModuleCatalogを生成

プロジェクト参照をなくせて、変更が少なく済みそうな[Moduleが格納されているフォルダを指定して読み込み](#Moduleが格納されているフォルダを指定して読み込み)が良さそうに見える。
他の動的に読み込める方法はバージョンや名前空間が変わるごとにメンテが必要となり大変そう。

## おわりに

今回はModuleの読み込む方法について確認しました。
個人的には動的に読み込める恩恵を受けられる方法が良いかと思いますが、Prismが使われているオープンソースでの主流についても把握したほうがよいと思いました。
次回、[08-ViewModelLocator](https://github.com/PrismLibrary/Prism-Samples-Wpf/tree/master/08-ViewModelLocator)について見ていこうと思います。