アーキテクチャ・ジャーナル

CAB および SCSF を使用したコンポジット スマート クライアントの設計

Mario Szpuszta
2009/03/16
Page1 Page2 Page3 Page4

コンポジット UI アプリケーション ブロック

 Microsoft Patterns & Practices チームによって 2005 年 11 月にリリースされた CAB (コンポジット UI アプリケーション ブロック) は、コンポジット スマート クライアントを実装するためのフレームワークです。CAB は、前述の要件をほとんどサポートしているため、上オーストリア州の Raiffeisen Banking Group 向けに “銀行シェル” を実装するための第 1 の選択肢となりました。CAB は、次の機能を提供します。

  • 一元的な構成に基づいて、独立していながら協調的なモジュールを共通シェルに動的に読み込む機能

  • ユーザー インターフェイス要素、ユーザー インターフェイス プロセス、クライアント側サービスなどの機能要素に対する複数レベルでの合成パターンのサポート

  • クライアント アプリケーションに読み込まれる機能部分間で緩やかに結合された通信に対するイベント ブローカ

  • すぐに使用できるコマンド パターン実装

  • MVC 実装用の基本クラス

  • 認証サービス、承認サービス、モジュールの場所、モジュール読み込みサービスなどのプラグ可能なインフラストラクチャ サービス用フレームワーク。

 他の多くのクライアント側アプリケーション フレームワークとは異なり、CAB はプラグインにより拡張可能な定義済みシェル アプリケーションには基づいていません。 CAB はむしろ、このシェルに動的にプラグインできる拡張可能なシェル アプリケーションとモジュールの両方を構築するためのフレームワークとなっています。このプロジェクトでは、その機能が役に立ちました。独自のフレームワーク構築の基盤となるメタフレームワークの役割を CAB が担ったためです。最終的に、CAB ではその機能をどれだけ使用し、その機能をどれだけ拡張または採用するかを選択できます。

 CAB に基づくコンポジット スマート クライアントの総合的な設計は、CAB がプラグインおよび拡張可能なアーキテクチャの構築に必要な機能をすべて含む基本的なフレームワークを提供している階層的なアプローチに従うことにしました。シェルおよびインフラストラクチャ ライブラリは、アプリケーションの基盤となります (CAB 上にフレームワークが構築される)。この基盤では、CAB 機能を使用して、ビジネス ユース ケースの実装を含むプラグイン (モジュール) が動的に読み込まれます。図 1 は、CAB ベースのコンポジット スマート クライアントの一般的なアーキテクチャを示しています。

図 1: CAB ベースのスマート クライアントのレイヤ

 もう 1 つの興味深い点は、CAB オブジェクト モデルでは、ユース ケース指向のアプローチにより、コンポジット スマート クライアントを設計できることです。そのオブジェクト モデルでは、ユース ケース コントローラ クラスは、ビューやそのコントローラなどの他のコンポーネント、またはプレゼンタのクラスとは明確に区別されます。WorkItem と呼ばれるユースケース コントローラ クラスは、ユース ケースに必要なすべての側面を統合します。つまり、これらのクラスはユース ケースに必要な状態を管理し、必要なビューやコントローラを統合し、ユース ケースを完成させるために必要なワークフローを管理し、最終的にこれらのコンポーネントすべてに対して管理された状態を提供します。このプロジェクトにおいて、WorkItem は図 1 に示す階層アーキテクチャと連携し、CAB を使用したコンポジットスマート クライアントを作成する開発プロセスにプロジェクト チームの構造を整合させるのに役立ちました。

 CAB ベースのスマート クライアントの開発プロセスに対しては、3 つの側面が影響を与えていることがわかりました。これらは、シェル、インフラストラクチャ サービス、および実際のユース ケースです。このため、開発には次の 3 つの主要な反復を推奨しました。

  1. ほとんどのユース ケースに共通する要件を細かく理解することから始めます。UI に関する共通の要件は、シェルに直接統合するか、少なくともシェルのレイアウトや設計に影響を与える候補となるものです。すべて (またはほとんど) のユース ケースに共通する UI 関連以外の機能は、一元的なサービスの候補となります。

  2. 詳細なユース ケース図を作成します。ユース ケースは、アプリケーション設計の中で WorkItem (およびサブ WorkItem) となる有力候補です。ユース ケース間の関係は、CAB のコマンド パターンまたはイベント ブローカ サブシステムを使用する候補となります。論理的に、同じアクター (社内のユーザーの役割) に対してユース ケースを実装する WorkItem など、密接に関係した WorkItem は、モジュールへのパッケージ化の有力候補となります。

  3. ユース ケース図を改良します。ユース ケース間の関係、およびユースケース (WorkItem) の再利用性とセキュリティの側面を分析します。この改良作業中に、WorkItem パッケージ化の若干のリファクタリングが必要になる場合があります。たとえば、他の WorkItem とは独立して再利用されるため、個別のモジュールにパッケージ化する必要がある WorkItem が見つかることがよくあります。

 詳細なユース ケース分析中に識別されたユース ケースは、CAB でWorkItem を識別するための基礎となります。WorkItem の設計にユース ケース指向のアプローチを使用する場合、各ユース ケースは 1 つのWorkItem にマッピングされます。図中のユース ケース間の関係は、2 つの項目のインジケータになります。第 1 に、これは 1 つの WorkItem 内に別の WorkItem が含まれていることを意味することがあります。第 2 に、このインジケータはこれらの WorkItem 間の通信につながります。通信は、サービス、イベント ブローカ、またはコマンドを経由して実装できます。

 通常、ユース ケース間の関係の改良および詳細分析は、どの種類の関係(親子または WorkItem 間の単なる通信) が存在するかを示すインジケータとなるので、使用する通信メカニズムを決定する上で役立ちます。この改良は、WorkItem をパッケージ化するための戦略にも影響します。したがって、広範な WorkItem の開発を開始する前に、この改良の反復を念頭に入れておくことが大切です。WorkItem の識別およびパッケージ化については、この記事で詳しく後述します。

シェルとインフラストラクチャ サービスの設計

 前述のように、最初のタスクの 1 つに、シェルの設計と実装があります。シェルは、実際のアプリケーションであり、基本的なクライアント サービスの読み込みと初期化、モジュールの読み込みと初期化に加えて、アプリケーションの基本的な UI の提供と WorkItem により読み込まれるビューのホストを行います。CAB は、このような機能のサポートに必要な基本クラスをすべて備えています。つまり、一元的な CAB 認証サービスに基づいてユーザーを認証でき、前述のように、ユーザーの役割に基づいて、いわゆるプロファイル カタログからモジュールを動的に読み込むことのできるシェル アプリケーション用の基本クラスを提供します。

 アプリケーションの基本的なユーザー インターフェイスはシェルによって提供され、これはアプリケーションに読み込まれるすべてのモジュール間で同じであるので、シェルにはいくつかの拡張ポイントを含め、ユース ケースすべてに共通する要件を満たす必要があります。シェルに統合するための有力候補となる共通ユーザー インターフェイス要素の一般的な例には、メニュー、ツール バー、タスク ペイン、およびナビゲーションペインがあります。ここで重要な点は、シェルには、単に拡張される部分(メニュー バーへのメニューの追加など) と、モジュールがアプリケーションに動的に読み込まれる際に完全に置換される部分があることです。これらの目的のために、CAB には独自のシェルの設計に利用できる 2 種類のシェル拡張ポイントが用意されています。これらは UIExtensionSite とWorkspace です。Workspace は、ユーザー インターフェイスの一部を完全に置換するために使用し、UIExtensionSite は、たとえばメニュー エントリの追加やツール ストリップ コントロールの追加など、シェルの既存の部分を拡張するために使用します。図 2 は、Visual Studio 2005 で設計された一般的なシェルの例を示しています。

図 2: Workspace および UIExtensionSite を含むシェルの一般的な例

 Workspace と UIExtensionSite は、スマート クライアント アプリケーションに読み込まれるすべてのサービスおよびモジュールで一般的に使用できます。CAB では、次のようにごく一般的な方法でこれらにアクセスできます。

workItem.UIExtensionSites["SiteName"]Add<ToolStripButton>(
new ToolStripButton());

 ただし、密結合やエラーを避けるために、シェルおよびシェルを追加するコンポーネントの間には間接層を設けることをお勧めします。シェルが他のコンポーネントに提供する必要のある機能に基づいて、シェルを拡張するためにシェルによって実装されるインターフェイス (またはシェルの主要なビュー プレゼンタ) を設計し、図 3 に示すように、CAB の他のコンポーネントによって使用される一元的なサービスとしてシェルを登録します。

図 3: 一元的なサービスとして提供されるカスタム IShellExtension インターフェイスのシェル実装

 これは、非常に単純でありながら強力な概念です。スマート クライアントに読み込まれるコンポーネント (WorkItem を含むモジュールまたは一元的なサービスを含むモジュール) では、Workspace および UIExtensionSite の名前に関する詳細を把握する必要がないためです。スマート クライアントに読み込まれるコンポーネントは、次のようにしてこれらのサービスにアクセスできます。

IShellExtensionService ShellService =
WorkItem.Services.Get<IShellExtensionService>();
ShellService.AddNavigationExtension(
"Some new Menu", null, someCommand);

 ここでも、この IShellExtension インターフェイスの実装では、既存のCAB インフラストラクチャを利用して、シェル UI 設計をシェル サービスの実装と切り離すことができますが、広範にわたる大量の WorkItem を作成している開発者が UIExtensionSite の名前などのシェルの詳細を把握する必要はありません。また、このようなシェル サービスを経由して、シェルに統合されるメッセージングやヘルプ システムなどの他のシェル関連機能を分離することもできます。ただし、シェル インターフェイスにはシェル UI 関連の機能のみを表示することが重要です。つまりこれは、スマート クライアントに読み込まれるコンポーネントが、ウィンドウの左側に表示されるメニュー、ツール ストリップ、タスク バーを拡張するか、メッセージを共通のメッセージ ペインに追加 (このセクションで前に示した例を参照) するための適切なアクセス ポイントになります。

インフラストラクチャ サービス

 前述のように、インフラストラクチャ サービスは、スマート クライアントに読み込まれるモジュールおよびコンポーネントに共通する機能をカプセル化します。シェル インフラストラクチャとは異なり、これらのサービスは UI に固有のタスクとは結びついていません。これらは通常は、クライアント側のロジックをカプセル化します。追加設定なしの CAB は、認証サービスや、ある場所 (既定ではアプリケーションディレクトリに格納されている ProfileCatalog.xml ファイル) で構成されているモジュールのカタログを読み込むサービスなどの数多くのインフラストラクチャ サービスをもたらします。もちろん、独自のサービスを導入することもできます。CAB では導入されない一元的なインフラストラクチャ サービスの一般的な例は、次のとおりです。

  • ビジネス機能に関連する承認サービス (CAB ではモジュールを読み込むための承認を行いますが、モジュールやアプリケーション内で実行できる特定の操作に対する承認は行いません)

  • Web サービスの呼び出しとオフライン機能をカプセル化する Web サービス エージェントおよびプロキシ

  • WorkItem 全体のユーザー コンテキストを管理するコンテキスト サービス (この記事で後述される「コンテキストと WorkItem」を参照)

  • アプリケーション中心の構成にアクセスするためのサービス

  • ClickOnce を使用してプログラミングによる自動更新をバックグラウンドで行う展開サービス

 これまでで、共通したサービスのインターフェイスを定義することから作業を開始することが重要であることを学びました。CAB では、次のように種類に基づいて一元的なサービスを登録できるためです。

MessageDisplayService svc =
new MessageDisplayService(_rootWorkItem);
_rootWorkItem.Services.Add<IMessageDisplayService>(svc);

 インフラストラクチャ サービスは、実際のユース ケースの実装を含む他のモジュールが読み込まれる前に読み込まれる、個別のインフラストラクチャ モジュールにカプセル化する必要があります。


 INDEX
  [アーキテクチャ・ジャーナル]
  CAB および SCSF を使用したコンポジット スマート クライアントの設計
    1.コンポジット スマート クライアントのアーキテクチャ ガイダンス
  2.コンポジット UI アプリケーション ブロック
    3.WorkItemを識別するユース ケース指向とビジネス エンティティ指向のアプローチ
    4.WorkItemのパッケージ化とスマート クライアント ソフトウェア ファクトリ

インデックス・ページヘ  「アーキテクチャ・ジャーナル」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間