原文「Initializing Applications Using the Prism Library for WPF」
この項目では、WPFアプリケーションの起動や実行するためのPrismを取得するために発生する、必要があることに対処します。Prismアプリケーションは、アプリケーションの起動プロセスの間で、登録と設定を必要とします。
これは、アプリケーションのブートストラップとして知られています。Prismのブートストラップ・プロセスは、モジュール・カタログを作成し、設定する、Unityのような、依存関係注入コンテナを作成すること、UI構成のための既定の領域アダプタを設定すること、シェル・ビューを作成して、初期化すること、そして、モジュールを初期化することが含まれています。
ブートストラッパーとは、何でしょうか?
What Is a Bootstrapper?
ブートストラッパーは、Prismライブラリを使用して構築されるアプリケーションの初期化のための、信頼できるクラスです。ブートストラッパーを使用して、あなたは、Prism Libraryコンポーネントが、あなたのアプリケーションに、どのように接続するか詳細に制御できます。
Prism Libraryには、どんなコンテナの用途でも専門化することができる、既定のabstract Bootstrapper基底クラスが含まれています。ブートストラッパー・クラスのメソッドの多くは、仮想メソッドです。あなたは、適切な、あなた独自のユーザー定義したブートストラッパーの実装で、これらのメソッドを上書きすることができます。
Prism Libraryは、ほとんどのアプリケーションのために適切な、既定の実装を持つ、Bootstrapperから派生した、いくつかの追加の基底クラスを提供します。あなたのアプリケーション・ブートストラッパーを実装するための、残った唯一の段階は、シェルを作成し、初期化することです。
依存関係注入
Dependency Injection
Prismライブラリで構築されるアプリケーションは、コンテナに提供される依存関係注入に依存しています。ライブラリは、あなたが、他の依存関係注入コンテナを使用できる、Unityアプリケーション・ブロック(Unity)やManaged Add-in Framework(MAF)で動作するアセンブリを提供しています。ブートストラップ処理の一部は、このコンテナを設定し、そのコンテナに型を登録することです。
Prismライブラリには、あなたのアプリケーションの依存関係注入コンテナとして、UnityやMEFのどちらでも使用するために、必要な機能のほとんどを実装する、UnityBootstrapperとMefBootstrapperクラスが含まれています。先程の図に表示される段階に加えて、それぞれのブートストラッパーは、特有のいくつかの手順を、そのコンテナに追加します。
シェルを作成する
Dependency Injection
Prismライブラリで構築されるアプリケーションは、コンテナに提供される依存関係注入に依存しています。ライブラリは、あなたが、他の依存関係注入コンテナを使用できる、Unityアプリケーション・ブロック(Unity)やManaged Add-in Framework(MAF)で動作するアセンブリを提供しています。ブートストラップ処理の一部は、このコンテナを設定し、そのコンテナに型を登録することです。
Prismライブラリには、あなたのアプリケーションの依存関係注入コンテナとして、UnityやMEFのどちらでも使用するために、必要な機能のほとんどを実装する、UnityBootstrapperとMefBootstrapperクラスが含まれています。先程の図に表示される段階に加えて、それぞれのブートストラッパーは、特有のいくつかの手順を、そのコンテナに追加します。
シェルを作成する
Creating the Shell
従来のWindows Presentation Foundation (WPF)アプリケーションでは、スタートアップの統一リソース識別子 (URI)は、メイン・ウィンドウを起動するApp.xamlファイルに明記されています。
Prismライブラリで作成されたアプリケーションでは、シェルやメイン・ウィンドウを作成することは、ブートストラッパーの役割です。これは、シェルが表示される前に、登録する必要があるRegion Managerのような、シェルが、サービスに依存しているためです。
重要な決定事項
Key Decisions
あなたが、アプリケーションで、Prismライブラリを使用することに決めたあと、作成する必要がある、多くの追加の決定があります。:
- あなたは、あなたが、あなたの依存関係注入コンテナのために、MEF、Unityや他のコンテナを使用するかどうか、決める必要があります。これは、あなたが、他のコンテナのために、ブートストラッパーを作成する必要があるかどうかに関係なく、あなたが使用する、提供されたブートストラッパー・クラスに決定されるでしょう。
- あなたは、あなたのアプリケーションで、あなたが望むアプリケーション固有のサービスついて、考える必要があります。これらは、コンテナに登録する必要があります。
- 組み込みの記録サービスが、あなたの用途のために十分か、あるいは、あなたが、他のログの記録サービスを作成する必要があるかどうかを判断します。
- アプリケーションで、モジュールを、どのように見つけるかについて決定します。:明示されたコード宣言を通して、モジュールのコード属性は、ディレクトリ走査、設定やXAMLによって発見します。
この項目の残りは、より多くの詳細を提供します。
中心となる筋書き
Core Scenarios
起動シーケンスの作成は、あなたのPrismアプリケーションを構築する重要な部分です。この項目は、シェルを作成するために、ブートストラッパーをどのように作成し、それをカスタマイズし、依存関係注入コンテナを設定する、アプリケーション・レベルのサービスを登録します。そして、モジュールを、どのように読み込んで、初期化するかを説明します。
あなたのApplicationのために、ブートストラッパーを作成します。
Creating a Bootstrapper for Your Application
あなたが、あなたの依存関係注入コンテナとして使用するために、UnityやMEFのどちらも選択する場合、あなたのアプリケーションのための単純なブートストラッパーを作成することは簡単です。あなたは、MefBootstrapperやUnityBootstrapperのどちらも継承する新しいクラスを作成する必要があるでしょう。続いて、CreateShellメソッドを実装します。必要に応じて、あなたは、シェルに固有の初期化のために、InitializeShellメソッドを上書きするかもしれません。
CreateShellメソッドを実装する
Implementing the CreateShell Method
CreateShellメソッドは、開発者が、Prismアプリケーションのための最上位のウィンドーを指定することができます。シェルは、通常、MainWindowやMainPageです。あなたのアプリケーションのシェルクラスのインスタンスを返すことで、このメソッドを実装します。Prismアプリケーションでは、あなたのアプリケーションの要件に応じて、あなたは、シェル・オブジェクトを作成する、あるいは、コンテナからそれを解決することができます。
シェル・オブジェクトを解決するために、ServiceLocatorを使用する例は、次のコードの例で示されます。
protected override DependencyObject CreateShell()
{
return ServiceLocator.Current.GetInstance<Shell>();
}
備考 あなたは、多くの場合、特定の依存関係注入コンテナの代わりに、インスタンス型を解決するために、使用されているServiceLocatorを見るでしょう。ServiceLocatorは、コンテナを呼び出すことで、実装されています。それで、それは、コンテナに依存しないコードのための優れた選択になります。また、あなたは、直接参照することができ、ServiceLocatorの代わりにコンテナを使用することができます。
InitializeShellメソッドを実装する
Implementing the InitializeShell Method
あなたが、シェルを作成したあと、あなたは、シェルが、表示する準備ができていることを確実にするために、初期化手順を実行する必要があるかもしれません。ここに(WPFのためのモジュール方式のクイックスタート)、示されるように、WPFアプリケーションのために、あなたは、シェル・アプリケーション・オブジェクトを作成し、アプリケーションのメイン・ウィンドウとして、それを設定するでしょう。:
protected override void InitializeShell()
{
Application.Current.MainWindow = Shell;
Application.Current.MainWindow.Show();
}
InitializeShellの基本的な実装は、何もしません。基底クラスの実装を呼び出さないほうが、安全です。
モジュール・カタログを作成して、設定する
Creating and Configuring the Module Catalog
あなたが、モジュール・アプリケーションを構築している場合、あなたは、モジュール・カタログを作成して、設定する必要があります。Prismは、どんなモジュールが、アプリケーションに利用できるか追跡するために、具体的なIModuleCatalogインスタンスを使用します。そのモジュールは、ダウンロードするために、そして、モジュールが存在する場所で必要になるかもしれません。
ブートストラッパーは、仮想CreateModuleCatalogメソッドのカタログだけでなく、基本的な実装を参照するために、保護されたModuleCatalogプロパティを提供します。基本的な実装は、新しいModuleCatalogを返します。;しかしながら、このメソッドは、WPFのクイックスタートのためのMEFによるモジュラー性のQuickStartBootstrapperから、次のコードで示すように、代わりに、異なるIModuleCatalogインスタンスを与えるために、上書きできます。
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()
}
UnityBootstrapperとMefBootstrapperクラスの両方で、Runメソッドは、CreateModuleCatalogメソッドを呼び出し、そして、その次に、戻り値を使用して、クラスのModuleCatalogプロパティを設定します。あなたが、このメソッドを上書きする場合、あなたが、提供する機能を置き換えられるため、それは、基底クラスの実装を呼び出す必要はありません。モジュール方式の詳細については、「モジュール・アプリケーション開発」を参照してください。
Containerを作成して、設定する
Creating and Configuring the Container
Prismライブラリで作成されるアプリケーションでは、コンテナは重要な役割を果たします。Prismライブラリとアプリケーションの両方では、必要な依存関係とサービスを注入するために、そのコンテナに依存して、一番上に構築されます。コンテナ設定段階の間に、複数の中心的なサービスが、登録されます。これらの中心的なサービスに加えて、あなたは、それに関係するものとして、追加された機能を与える、アプリケーション固有のサービスを持っているかもしれません。
中心的なサービス
Core Services
次の表は、Prismライブラリで、アプリケーションではない中心的な特定のサービスの一覧を示します。
サービス・インターフェイス | 説明 |
---|---|
IModuleManager | アプリケーションのモジュールを読み出し、初期化するサービスのためのインターフェースを定義します。 |
IModuleCatalog | アプリケーション内のモジュールに関するメタデータが含まれています。 Prismライブラリは、複数の異なるカタログを提供します。 |
IModuleInitializer | モジュールを初期化します。 |
IRegionManager | レイアウトのための視覚的なコンテナの領域を登録し、読み出します。 |
IEventAggregator | イベントのコレクションは、パブリッシャとサブスクライバの間で疎く結合しています。 |
ILoggerFacade | ロギングメカニズムのためのラッパ、それで、あなたは、あなた独自のロギングメカニズムを選択することができます。EnterpriseLibraryLoggerAdapterクラスを通じて、どのように、あなたが、あなた独自のロガーを使用することができるかの例として、株トレーダーの参考になる実装(株トレーダーRI)は、アプリケーション・ブロックにログインしているエンタープライズ・ライブラリを使用します。ログの記録サービスは、CreateLoggerメソッドによって返される値を使用して、ブートストラッパーのRunメソッドでコンテナに登録されます。コンテナは、動作しないかかもしれない他のロガーを登録します。;その代わりに、CreateLoggerメソッドをブートストラッパーで上書きします。 |
IServiceLocator | Prismライブラリは、コンテナにアクセスできます。あなたが、ライブラリをカスタマイズ、あるいは、拡張したい場合、これは、役に立つかもしれません。 |
Prismでは、UnityBootstrapperとMefBootstrapperの2つのブートストラッパーから派生したクラスが利用できます。異なるコンテナを作成し、設定することは、それぞれに実装される同じような概念が含まれています。
UnityBootstrapper内に、コンテナを作成して、設定する
Creating and Configuring the Container in the UnityBootstrapper
UnityBootstrapperクラスのCreateContainerメソッドは、UnityContainerの新しいインスタンスを簡単に作成し、返します。ほとんどの場合、 あなたは、この機能を変更する必要ありません。;しかしながら、メソッドは、仮想です。それによって、その柔軟性を提供します。
コンテナが作成されたあと、それは、おそらく、あなたのアプリケーションのために設定されている必要があります。ここに、示されるように、UnityBootstrapper内のConfigureContainerの実装は、既定で、いくつかの中心的なPrismサービスを登録します。:
メモ: その初期化されたメソッドで、モジュールが、モジュール・レベルのサービスに登録される時は、この1つの例です。
// UnityBootstrapper.cs
protected virtual void ConfigureContainer()
{
...
if (useDefaultConfiguration)
{
RegisterTypeIfMissing(typeof(IServiceLocator), typeof(UnityServiceLocatorAdapter), true);
RegisterTypeIfMissing(typeof(IModuleInitializer), typeof(ModuleInitializer), true);
RegisterTypeIfMissing(typeof(IModuleManager), typeof(ModuleManager), true);
RegisterTypeIfMissing(typeof(RegionAdapterMappings), typeof(RegionAdapterMappings), true)
RegisterTypeIfMissing(typeof(IRegionManager), typeof(RegionManager), true);
RegisterTypeIfMissing(typeof(IEventAggregator), typeof(EventAggregator), true);
RegisterTypeIfMissing(typeof(IRegionViewRegistry), typeof(RegionViewRegistry), true);
RegisterTypeIfMissing(typeof(IRegionBehaviorFactory), typeof(RegionBehaviorFactory), true);
RegisterTypeIfMissing(typeof(IRegionNavigationJournalEntry), typeof(RegionNavigationJournalEntry), false);
RegisterTypeIfMissing(typeof(IRegionNavigationJournal), typeof(RegionNavigationJournal), false);
RegisterTypeIfMissing(typeof(IRegionNavigationService), typeof(RegionNavigationService), false);
RegisterTypeIfMissing(typeof(IRegionNavigationContentLoader), typeof(UnityRegionNavigationContentLoader), true);
}
}
ブートストラッパーのRegisterTypeIfMissingメソッドは、サービスが、既に登録されているかを判断します。-それは、それを2回登録しません。これは、設定を通して、既定の登録をオーバーライドすることができます。また、あなたは、既定で、どんなサービスでも登録を止めることができます。;これを実行するには、重ねて読み込んだBootstrapper.Runメソッドを使用して、falseを渡します。また、あなたは、イベント・アグリゲーターのように、あなたが、使用したいと思わない、ConfigureContainerメソッドと使えないサービスを上書きすることができます。
備考 あなたが、既定の登録を止める場合、あなたは、手動で必要とされるサービスを登録する必要があります。
ConfigureContainerの既定の動作を拡張するために、モジュール方式ののためのWPFの(Unityで)クイックスタートから、QuickStartBootstrapperから、次のコードで示すように、簡単に、あなたのアプリケーションのブートストラッパーに、オーバーライドを追加し、基本的な実装を必要に応じて呼びます。この実装は、基本的なクラスの実装を呼び出します。IModuleTrackerの具体的な実装として、ModuleTracker型を登録します。そして、UnityによるCallbackLoggerの単体インスタンスとして、callbackLoggerを登録します。
protected override void ConfigureContainer()
{
base.ConfigureContainer();
this.RegisterTypeIfMissing(typeof(IModuleTracker), typeof(ModuleTracker), true);
this.Container.RegisterInstance<CallbackLogger>(this.callbackLogger);
}
MefBootstrapper内に、Containerを作成して、設定する
Creating and Configuring the Container in the MefBootstrapper
MefBootstrapperクラスのCreateContainerメソッドは、いくつかのことを行います。まず、それは、AssemblyCatalogとCatalogExportProviderを作成します。CatalogExportProviderは、MefExtensionsアセンブリに、いくつかのPrismの型のために、既定のエクスポートを提供できます。そして、さらに、あなたは、既定の型の登録をオーバーライドできます。続いて、CreateContainerは、CatalogExportProviderを使用して、CompositionContainerの新しいインスタンスを作成して、返します。ほとんどの場合、あなたは、この機能を変更する必要ありません。;しかしながら、メソッドは、仮想です。それによって、その柔軟性を提供します。
コンテナが作成されたあと、それは、あなたのアプリケーションのために設定されている必要があります。次のコードの例に示すように、MefBootstrapper内のConfigureContainerの実装は、既定で、いくつかの中心的なPrismサービスを登録します。あなたが、このメソッドを上書きする場合、あるいは、あなたが、あなたの実装で、これらのサービスを提供したい場合、あなたが、中心的なPrismサービスを登録するために、基底クラスの実装を呼び出す必要があるかどうか、慎重に考えます。
protected virtual void ConfigureContainer()
{
this.RegisterBootstrapperProvidedTypes();
}
protected virtual void RegisterBootstrapperProvidedTypes()
{
this.Container.ComposeExportedValue<ILoggerFacade>(this.Logger);
this.Container.ComposeExportedValue<IModuleCatalog>(this.ModuleCatalog);
this.Container.ComposeExportedValue<IServiceLocator>(new MefServiceLocatorAdapter(this.Container));
this.Container.ComposeExportedValue<AggregateCatalog>(this.AggregateCatalog);
}
備考 MefBootstrapperでは、Prismの中心的なサービスは、単体としてコンテナに追加されます。それで、それらは、アプリケーションを通して、コンテナに配置することができました。
CreateContainerとConfigureContainerメソッドを提供することに加えて、また、MefBootstrapperは、MEFで使用されるAggregateCatalogを作成し、設定するために、2つのメソッドを提供します。CreateAggregateCatalogメソッドは、AggregateCatalogオブジェクトを簡単に作成し、返します。MefBootstrapperの他のメソッドのような、CreateAggregateCatalogは、仮想です。そして、必要に応じてオーバーライドされることができます。
ConfigureAggregateCatalogメソッドは、あなたが、いやおうなしに、AggregateCatalogに型登録を追加できます。例えば、ここに、示されるように、MEFクイックスタートによるモジュラー性から、QuickStartBootstrapperは、ModuleAとModuleCをAggregateCatalogに明示的に追加します。:
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.ModuleA).Assembly));
this.AggregateCatalog.Catalogs.Add(
new AssemblyCatalog(typeof(ModuleC.ModuleC).Assembly));
// Module B and Module D are copied to a directory as part of a post-build step.
// 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.
// モジュールBとモジュールDは、ビルド後の手順の一部としてディレクトリへコピーされます。
// これらのモジュールは、プロジェクトでは参照されず、ディレクトリを調べることによって発見されます。
// どちらのプロジェクトも、そのディレクトリに、それら自身をコピーするために、ビルド後の手順を持っています。
DirectoryCatalog catalog = new DirectoryCatalog("DirectoryModules");
this.AggregateCatalog.Catalogs.Add(catalog);
}
詳細情報
More Information
MEF、AggregateCatalogとAssemblyCatalogの詳細については、MSDNのManaged Extensibility Frameworkの概要を参照してください。