Modularity QuickStarts Using the Prism Library 5.0 for WPF(原文)
パターンと実践 ディベロパー・センター
Microsoft Prism Library 5.0 for WPFの開発者のガイドから:
Modulatiryクイックスタートのソース・コード:
- ダウンロード Unityバージョン
※訳注 Visual Studio Community 2010以外は、そのままでは動きません
MEFが、.Net Freameworkにはじめから含まれているのは、.Net 4.0(Visual Studio 2010)だけです。それ以降の環境で利用するためには、Microsoft CompositionをNugetマネージャーを使って取得しておく必要があります。一度、パッケージをインストールすると意識することがないため、「Microsoft Composition」をインストールする必要があることに触れていない情報が多いので、提供されているサンプルが動かない場合は確認してみましょう。
- ダウンロード MEFバージョン
このトピックに含まれるクイックスタートは、Prismライブラリを使用して、モジュールWPFアプリケーションを、 そのように作成するかを説明するコード・サンプルを提供しています。サンプルは、どのように、コード化、発見、そして、初期化するかを説明します。:
- モジュールを作成する。モジュールは、IModuleインターフェイスを実装するクラスです。 宣言型の属性は、名前モジュールに使用され、初期化を制御し、依存関係を定義することができます。
- モジュールの登録。モジュールは、以下方法で登録することができます。:
- 直接コードで。モジュールは、アプリケーション・コード内のモジュール・カタログで、直接、登録することができます。 この方法を使用して、あなたは、あなたのアプリケーションに含まれる必要があるモジュールを決定するために、条件付きロジックを使用できます。 コード中に追加されたモジュールは、実行時に、読み込まれる代わりに、アプリケーションによって参照されます。
- 使用する設定。Prismは、設定ファイルを読み込むことによって、モジュール・カタログと一緒にモジュールを登録することができます。 設定内で宣言したモジュールは、モジュールを読み込み、そして、アプリケーションから独立して初期化することができます。
- ディレクトリ検査を使用して、ディレクトリは、ディレクトリ、 そして、検出するモジュール内で、アセンブリに読み込ことで、指定し、そして、検査することができます。
- モジュールの依存関係を登録。モジュールは、他のモジュールと依存関係を持つことができます。 Prismは、循環した依存関係と重複するモジュールの検出を含む、依存関係の管理を提供します。
- モジュールを初期化する。Prismは、次の2つの初期化モードをサポートしています。:
- 利用できるとき。モジュールは、利用できるとすぐに、初期化することができます。 アプリケーションでダウンロードされたモジュールは、スタートアップの間に初期化されます。 ダウンロードするために、背後で設定されるモジュールは、ダウンロードが完了した直後に、初期化されます。
- 要求された時。モジュールは、アプリケーション・コードが要求するとき、初期化されることができます。アプリケーションが、モジュールを要求するとき、 背後で、ダウンロードされるモジュールは、ダウンロードを開始します。そして、その次に、それらは、ダウンロードが完了するとすぐに初期化されます。
- 背後で、モジュールをダウンロードする。背後でダウンロードすると、Silverlightアプリケーションにとって、
最も有用ですが、デスクトップ・アプリケーションは、アセンブリが、検出、そして、読み込まれることで、
次に、同じ進行中と完了イベントを利用することができます。:
- 進行中を表示する。アプリケーションは、バイト数とパーセンテージの進行を表示するために、 ダウンロードされたモジュールとして、プログレス変更イベントを購読することができます。
- ダウンロード完了時の動作。アプリケーションは、ロードモジュールを購読することができます- 完了イベントは、モジュールが、読み込まれ、そして、初期化された後、追加の動作を実行します。
- 異なる依存関係注入コンテナを活用する。伝統的に、QuickStartsは、
コア・ライブラリー・コードが、コンテナに依存していない間、Unityコンテナを使用して説明しました。
.NET Framework 4に、拡張管理フレームワーク(MEF)を追加した、
それぞれ異なるコンテナを使用する2つのQuickStartsがあります。:
- ModularityWithMef。依存関係注入コンテナとして、MEFを使用するとき、このQuickStartは、モジュール方式を説明します。 Prismは、ModuleCatalogとMEFのComposablePartsCatalogを統合するために、MEFの宣言型の属性モデルを活用します。
- ModularityWithUnity。このQuickStartは、依存関係注入コンテナとして、Unityを使用するとき、モジュール方式を説明します。
筋書き
Scenarios
この項目は、両方のモジュール型のQuickStartsに含まれるシナリオを説明します。 各々のQuickStartは、6つのモジュールで構成されます。:ModuleA、ModuleB、ModuleC、ModuleD、ModuleEとModuleF。 各々のモジュールは、モジュールが、どのように発見され、ダウンロードされ、初期化されるかという、測面を説明します。
Module | Defined in | Initialized | Downloaded | Depends on |
---|---|---|---|---|
A | Code | When available | With application | D |
B | Directory | On demand | In background | |
C | Code | On demand | With application | |
D | Directory | When available | In background | |
E | Configuration | On demand | In background | |
F | Configuration | On demand | In background | E |
各々のQuickStartは、コントロールとして、各々のモジュールを表示します。それが初期化されたかどうかに関係なく、 コントロールが示すモジュール、進行中をダウンロードしているディスプレイ、そして、オンデマンドのモジュールは、 初期化を要求するためにクリックされることができます。また、コントロールは、その現在の初期状態を紹介するツールチップと発見情報を提供します。 下の方に、各々のクイックスタート・ページは、配列とモジュール-読み込み詳細を起動することから、ログエントリーを表示するテキストボックスです。 次に示す図は、MEFクイックスタートによるモジュール方式のメインページを示しています。
モジュール方式のクイックスタート・ユーザー・インターフェイス
Modularity QuickStart user interface
クイックスタートを構築して、そして、実行する
Building and Running the QuickStarts
このクイックスタートは、.NET Framework 4.5.1とMicrosoft Visual Studio 2012以降を必要とします。
ModularityWithMef QuickStartを構築して、実行するには、
To build and run the ModularityWithMef QuickStart
- Visual Studioでは、ソリューション・ファイルQuickstarts\Modularity\Desktop\ModularityWithMef\ModularityWithMef.Desktop.slnを開きます。
- Buildメニューで、ソリューションのリビルドをクリックします。
- QuickStartを実行するために、F5を押してください。
ModularityWithUnity QuickStartを構築して、実行するには、
To build and run the ModularityWithUnity QuickStart
- Visual Studioでは、+solutionファイルQuickstarts\Modularity\Desktop\ModularityWithUnity\ModularityWithUnity.Desktop.slnを開けます。
- Buildメニューで、ソリューションのリビルドをクリックします。
- QuickStartを実行するために、F5を押してください。
ModularityWithUnity QuickStartを構築して、実行するには、
To build and run the ModularityWithUnity QuickStart
- Visual Studioでは、solutionファイルQuickstarts\Modularity\Desktop\ModularityWithUnity\ModularityWithUnity.Desktop.slnを開けます。
- Buildメニューで、ソリューションのリビルドをクリックします。
- QuickStartを実行するために、F5を押してください。
備考
両方のクイックスタートは、ビルドが成功した後、自動的に、フォルダ内のモジュール・アセンブリに格納する、各々のモジュール・プロジェクトに設定されたビルド後のイベントを持っています。実行可能なアプリケーションとして、モジュールBとDは、DirectoryModulesフォルダにコピーされ、そして、モジュールEとFは、同じ位置にコピーされます。 ビルド後のイベント設定を表示するには、モジュール・プロジェクトを右クリックし、そして、プロパティをクリックします。Propertiesダイアログボックスで、Build Eventsタブをクリックします。
次のコードは、Post-buildイベント・コマンド・ライン・テキストボックスに、ビルド後のイベント・コマンドを表示します。xcopy "$(TargetDir)*.*" "$(SolutionDir)ConfigurationModularity\bin\$(ConfigurationName)\DirectoryModules\" /Y
チュートリアル
Walkthrough
シナリオを検討するため、QuickStartを構築して、実行するための手順を実行します。:
- 次の図に示すように、メイン・ウィンドウは、モジュールの初期状態を表示するそれぞれのモジュールの設定を表示します。
アプリケーションが起動すると、モジュールDとモジュールAは、発見され、初期化されます。
MEFクイックスタートによるモジュール方式のメインページ
Main page of Modularity with MEF QuickStart
モジュールDは、アプリケーションの起動時に、ディレクトリ検査によって発見されます。それが利用可能で、モジュールDに依存する場合、モジュールAが初期化されます。 モジュールDが、読み込まれた後、モジュールAが、初期化されます。一番下の追跡ウィンドウは、アプリケーションが初期化されるので、メッセージを表示します。
備考
依存関係が指定されていない場合、モジュールの読込順序は非決定論的です。 - Module Aコントロール上に、カーソルを重ねます。次の図に示すように、
Module Aコントロールに、マウスカーソルを重ねると、説明を表示するツールチップが、表示されます。
モジュール情報ツールチップ
Module Information tooltip
- あなたが、モジュールにポインターを重ねると、その状態、発見、初期化、 ダウンロード・タイミングと依存関係についての情報を表示するツールチップが、表示されます。
- Module BとModule Cコントロールをクリックします。各々のモジュールの初期化状態の変化として、ビジュアル・コントールは更新されます。
次の図に示すように、Module BコントロールやModule Cコントロールがクリックされると、そのモジュールは読み込まれます。
読み込まれたモジュールのスクリーン・ショット
Screen shot of module loaded
- Module Bは、ディレクトリ検査によって発見され、そして、Module Cは、アプリケーションによって参照されます。
両方のモジュールは、要求に応じて読み込まれます。
Module Fコントロールをクリックします。Module Fコントロールがクリックされると、次の図で示すように、Module EとModule Fは読み込まれます。
Module Eのスクリーン・ショットは、Module Fを読み込むために、読み込まれます。
Screen shot of Module E getting loaded to load Module F
Module Fは、まず、その初期化を完了することに注意してください。しかし、依存関係のため、Module Eの初期化の後まで初期化されません。
実装の詳細
Implementation Details
QuickStartsは、モジュール方式内の重要なコンポーネントを強調表示します。次の項目は、クイックスタートの重要な成果物を説明します。
Bootstrapperは、アプリケーションの仕様をサポートするために、 MefBootstrapperかUnityBootstrapperのいずれかの、いくつかのメソッドをオーバーライドします。 これらの項目では、依存関係注入コンテナの重要な違いを説明します。
アプリケーションの起動
Application Startup
アプリケーションは、アプリケーションを起動して、メイン・ウィンドウを初期化するQuickStartBootstrapperを使用します。
C#
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
// The bootstrapper will create the Shell instance, so the App.xaml
// does not have a StartupUri.
// ブートストラッパーは、Shellのインスタンスを作成するでしょう。それで、App.xamlは、StartupUriを持っていません。
QuickStartBootstrapper bootstrapper = new QuickStartBootstrapper();
bootstrapper.Run();
}
Bootstrapperは、メイン・ウィンドウを作成し、そして、表示するために、CreateShellとInitializeShellメソッドをオーバーライドします。
C#
protected override DependencyObject CreateShell()
{
return ServiceLocator.Current.GetInstance<Shell>();
}
protected override void InitializeShell()
{
base.InitializeShell();
Application.Current.MainWindow = (Window)this.Shell;
Application.Current.MainWindow.Show();
}
モジュールを作成する。
Creating Modules
このQuickStartで使用する、6つのモジュールは、IModuleインターフェイスを実装することによって作成されます。 属性は、選択された依存関係注入コンテナ(つまり、UnityやMEF)に依存して、追加されています。
C#
// when using Unity
[Module(ModuleName = WellKnownModuleNames.MyModule)]
[ModuleDependency(WellKnownModuleNames.DependentModule)]
public class MyModule: IModule
{
...
}
Unityを使用するとき、属性は、モジュールに名前を付け、そして、依存関係を指定するために、使用されます。
C#(ModuleA.cs)
// when using MEF
[ModuleExport(typeof(ModuleA), DependsOnModuleNames = new string[] { "ModuleD" })]
public class ModuleA : IModule
{
...
}
MEFを使用するとき、ModuleExport属性は、MEFが、IModuleインターフェイスから派生している、適切なデータ型を発見できます。; 加えて、それは、追加のモジュールのメタデータを指定する機能を提供します。
モジュールの登録
Registering Modules
このQuickStartでは、幾つかのモジュールは、アプリケーションによって直接参照され、ディレクトリを調べることによって発見され、 あるいは、設定ファイルを読み込むことによって登録されます。
C#
// when using Unity
// Unityを使用するとき、
protected override IModuleCatalog CreateModuleCatalog()
{
return new AggregateModuleCatalog();
}
C#
// when using Unity
// Unityを使用するとき、
protected override void ConfigureModuleCatalog()
{
// Module A is defined in the code.
// Module Aは、コード内で定義されます。
Type moduleAType = typeof(ModuleA);
ModuleCatalog.AddModule(new ModuleInfo(moduleAType.Name,
moduleAType.AssemblyQualifiedName));
// Module C is defined in the code.
// Module Cは、コード内で定義されます。
Type moduleCType = typeof(ModuleC);
ModuleCatalog.AddModule(new ModuleInfo()
{
ModuleName = moduleCType.Name,
ModuleType = moduleCType.AssemblyQualifiedName,
InitializationMode = InitializationMode.OnDemand
});
// Module B and Module D are copied to a directory as part of a post-build step.
// Module BとModule Dは、ビルド後の手順の一部として、ディレクトリへコピーされます。
// These modules are not referenced in the project and are discovered by
// inspecting a directory.
// これらのモジュールは、プロジェクトでは参照されず、ディレクトリを調べることによって発見されます。
// Both projects have a post-build step to copy themselves into that directory.
// どちらのプロジェクトも、そのディレクトリに、それら自身をコピーするために、ビルド後の手順を持っています。
DirectoryModuleCatalog directoryCatalog = new DirectoryModuleCatalog() { ModulePath = @".\DirectoryModules" };
((AggregateModuleCatalog)ModuleCatalog).AddCatalog(directoryCatalog);
// Module E and Module F are defined in configuration.
// Module EとModule Fは、設定で定義されています。
ConfigurationModuleCatalog configurationCatalog = new ConfigurationModuleCatalog();
((AggregateModuleCatalog)ModuleCatalog).AddCatalog(configurationCatalog);
}
備考
ModuleCatalogを使用する複数の方法を説明するために、Unityを使用するQuickStartは、 IModuleCatalogから派生するAggregateModuleCatalogを実装しています。 このクラスは、出荷アプリケーションで、使用されることを意図していません。
MEFを使用するとき、AggregateCatalogは、モジュールと型検出を提供しています。 この場合、QuickStartBootstrapperは、ConfigureAggregateCatalogテンプレート・メソッドとMEFと一緒にレジスター・アセンブリをオーバーライドします。 ModuleCatalogは、依然として、設定ファイルを読み込むことによって、登録モジュールのために使用されています。
C#
// when using MEF MEFを使用するとき、
protected override IModuleCatalog CreateModuleCatalog()
{
// When using MEF, the existing Prism ModuleCatalog is still the place to
// configure modules via configuration files.
// MEFを使用するとき、まだ、既存のPrismのModuleCatalogは、
// 構成ファイルによってモジュールを設定するための場所です。
return new ConfigurationModuleCatalog();
}
C#
// when using MEF MEFを使用するとき、
protected override void ConfigureAggregateCatalog()
{
base.ConfigureAggregateCatalog();
// Add this assembly to export ModuleTracker.
// ModuleTrackerをエクスポートするために、このアセンブリを追加します
this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(QuickStartBootstrapper).Assembly));
// Module A is referenced in in the project and directly in code.
// Module Aは、コード内のプロジェクトとディレクトリ内で、参照されています。
this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(ModuleA).Assembly));
this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(ModuleC).Assembly));
// Module B and Module D are copied to a directory as part of a post-build step.
// モジュールBとモジュールDは、ビルド後の手順の一部としてディレクトリへコピーされます。
// These modules are not referenced in the project and are discovered by
// inspecting a directory.
// これらのモジュールは、プロジェクトでは参照されず、ディレクトリを調べることによって発見されます。
// Both projects have a post-build step to copy themselves into that directory.
// どちらのプロジェクトも、そのディレクトリに、それら自身をコピーするために、ビルド後の手順を持っています。
DirectoryCatalog catalog = new DirectoryCatalog("DirectoryModules");
this.AggregateCatalog.Catalogs.Add(catalog);
}
モジュールを読み込む
Loading Modules
このクイックスタートは、起動時に、そして、要求に応じてモジュールを読み込み、進行状況を表示し、そして、モジュール間の依存関係の取り扱いを説明します。
備考
このQuickStartは、モジュールの初期状態を追跡することを助ける追加のクラスを持っています。 これらのクラスは、実演のみを目的としています。そして、出荷アプリケーションを意図していません。
Shellユーザー・インターフェイスには、各々のモジュールのためのModuleControlが含まれています。 また、Shellは、そのDataContextとして、ModuleTrackerクラスを持っています。 ModuleTrackerには、各々のモジュールのためのModuleTrackingStateが含まれています。 ModuleControlデータは、ModuleTrackingStateに結合します。 そして、モジュールのダウンロードし、そして、初期化された状態を視覚的に表示するために、カスタム・スタイルを使用します。
Shellは、モジュールを読み込むために、ユーザー・インターフェイス(UI)からの要求に対応します。 そして、ModuleManager.LoadModuleメソッドを呼び出します。
C#
private void ModuleC_RequestModuleLoad(object sender, EventArgs e)
{
// The ModuleManager uses the Async Events pattern.
// ModuleManagerは、Async Eventsパターンを使用します。
this.moduleManager.LoadModule(WellKnownModuleNames.ModuleC);
}
ModuleManager.ModuleDownloadProgressChangedイベントを購読することによって、シェルは、ダウンロードの進行状況を通知します。
C#
this.moduleManager.ModuleDownloadProgressChanged += this.ModuleManager_ModuleDownloadProgressChanged;
C#
Shellは、モジュールがダウンロードされ、そして、初期化されるとき、ModuleManager.LoadModuleCompletedイベントを購読することによって、通知します。
C#
this.moduleManager.LoadModuleCompleted += this.ModuleManager_LoadModuleCompleted;
C#
void ModuleManager_LoadModuleCompleted(object sender, LoadModuleCompletedEventArgs e)
{
this.moduleTracker.RecordModuleLoaded(e.ModuleInfo.ModuleName);
}
主要なモジュール方式に対応するクラス
Key Modularity Classes
以下は、モジュール方式のクイックスタートで使用されるいくつかの主要なクラスです。:
- ModuleCatalog。このクラスは、アプリケーション内の、モジュールとモジュール・グループのためのメタデータを分類するための、役割を果たします。
- ModuleManager。このクラスは、モジュールの初期化を調整します。それは、モジュールの検索とその後の初期化を管理します。
- ModuleInitializer。このクラスは、モジュールのインスタンスを作成する際に、ModuleManagerを支援します。
- IModuleTypeLoader。これは、ファイルシステムやリモート・サーバからのモジュールを取得するための(XapModuleTypeLoaderクラスのような)派生型のためのインターフェイスです。
- Bootstrapper/MefBootstrapper/UnityBootstrapper.。このクラスは、モジュールPrismアプリケーションの開始、そして、初期化内に、アプリケーションを支援します。
受入検査
Acceptance Tests
モジュール方式のクイックスタートには、UnityとMEF QuickStartsのための受入検査の分離したソリューションが含まれています。 受入検査では、あなたが、一連の手順に従うとき、アプリケーションが、どのように動作する必要があるかを説明します。 あなたは、さまざまな使い方をする、アプリケーションの機能的挙動を調べるために、受入検査を使用することができます。
モジュール方式のクイックスタート受入検査を実行するには
To run the Modularity QuickStarts acceptance tests
- Visual Studioでは、次のソリューション・ファイルのいずれかを開きます。:
- QuickStarts\Modularity\ModularityWithUnity.Tests.AcceptanceTest\ModularityWithUnity.Tests.AcceptanceTest.sln
- QuickStarts\Modularity\ModularityWithMEF.Tests.AcceptanceTest\ModularityWithMEF.Tests.AcceptanceTest.sln
- ソリューションを構築します。
- Test Explorerを開きます。
- ソリューションを構築した後、Visual Studioは、テストを捜し出します。受入検査を実行するために、Run Allボタンをクリックします。
結論
Outcome
あなたが、受入検査を実行するとき、あなたは、Windowsのクイックスタートを確かめる必要があります。 そして、テストは、自動的に、ユーザー・インターフェイスと相互作用します。 テストが渡された最後に、あなたは、すべてのテストが渡されたことを確かめる必要があります。
詳細情報
モジュール方式の詳細については、モジュール・アプリケーション開発(原文)を参照してください。
Prismに含まれる、他のコードサンプルについて学ぶためには、次のトピックを参照してください。:
- 株トレーダーの参考になる実装
- インタラクティブ性のクイックスタート
- MVVMクイックスタート
- 命令のクイックスタート
- UI構成のクイックスタート
- 状態に基づいたナビゲーションのクイックスタート
- 表示を切り替えるナビゲーションのクイックスタート
- イベント集約のクイックスタート