プロジェクト サブタイプのデザイン

プロジェクト サブタイプを使用すると、Microsoft Build Engine (MSBuild) に基づいて VSPackage によってプロジェクトを拡張することができます。 集計を使用すると、Visual Studio に実装されているコア マネージド プロジェクト システムの大部分を再利用しながら、特定のシナリオに合わせて動作をカスタマイズできます。

以下のトピックでは、プロジェクト サブタイプの基本的な設計と実装について詳しく説明します。

  • プロジェクト サブタイプの設計。

  • 複数レベルの集計。

  • サポート インターフェイス。

プロジェクト サブタイプの設計

プロジェクト サブタイプの初期化は、メインの IVsHierarchyIVsProject の各オブジェクトを集計することで実現されます。 この集計を使用すると、プロジェクト サブタイプにより、ベース プロジェクトのほとんどの機能をオーバーライドしたり、拡張したりすることができます。 プロジェクト サブタイプにより、IVsHierarchy を使用するプロパティ、IOleCommandTargetIVsUIHierarchy を使用するコマンド、IVsProject3 を使用するプロジェクト項目管理を初めて処理できるようになります。 また、プロジェクト サブタイプを使用して、以下を拡張することもできます。

  • プロジェクト構成オブジェクト。

  • 構成に依存するオブジェクト。

  • 構成に依存しない参照オブジェクト。

  • プロジェクト オートメーション オブジェクト。

  • プロジェクト オートメーションのプロパティ コレクション。

プロジェクト サブタイプによる拡張性の詳細については、「プロジェクト サブタイプによって拡張されるプロパティとメソッド」を参照してください。

ポリシー ファイル

Visual Studio 環境には、ポリシー ファイルの実装でプロジェクト サブタイプを使用してベース プロジェクト システムを拡張する例が用意されています。 ポリシー ファイルを使用すると、ソリューション エクスプローラー、[プロジェクトの追加] ダイアログ ボックス、[新しい項目の追加] ダイアログ ボックス、[プロパティ] ダイアログ ボックスなどの機能を管理して、Visual Studio 環境を整えることができます。 IVsFilterAddProjectItemDlgIOleCommandTargetIVsUIHierarchy の実装を通じて、ポリシー サブタイプにより、これらの機能はオーバーライドおよび拡張されます。

集計メカニズム

この環境のプロジェクト サブタイプ集計メカニズムは、複数レベルの集計をサポートしているため、フレーバー プロジェクトにさらにフレーバーを付けることで、高度なサブタイプを実装できます。 また、IVsProjectFlavorCfg などのプロジェクト サブタイプのサポート オブジェクトは、複数レベルの階層化を許可するように設計されています。 COM と COM の集計規則の制約に従って、プロジェクト サブタイプとベース プロジェクトを協調的にプログラムして、内部サブタイプまたはベース プロジェクトがメソッド呼び出しの委任と参照カウントの管理に適切に参加できるようにする必要があります。 つまり、集計対象のプロジェクトは、集計をサポートするようにプログラムする必要があります。

次の図は、複数レベルのプロジェクト サブタイプ集計の概略図です。

Visual Studio multilevel projectflavor graphic

複数レベルのプロジェクト サブタイプ集計は、3 つのレベルで構成されます。ベース プロジェクトは、プロジェクト サブタイプごとに集計され、さらに高度なプロジェクト サブタイプによって集計されます。 この図では、Visual Studio プロジェクト サブタイプ アーキテクチャの一部として用意されているサポート インターフェイスの一部に焦点を当てています。

展開メカニズム

プロジェクト サブタイプによって拡張される多くのベース プロジェクト システム機能の中に、展開メカニズムがあります。 IVsProjectCfgProvider に対して QueryInterface を呼び出すことで取得される構成インターフェイス (IVsDeployableProjectCfgIVsBuildableProjectCfg など) を実装することにより、プロジェクト サブタイプは展開メカニズムに影響します。 プロジェクト サブタイプと高度なプロジェクト サブタイプの両方によって、異なる構成実装が追加されるシナリオの場合、ベース プロジェクトから、高度なプロジェクト サブタイプの IUnknown に対して QueryInterface が呼び出されます。 ベース プロジェクトから要求されている構成実装が内側のプロジェクト サブタイプに含まれている場合、高度なプロジェクト サブタイプから、内側のプロジェクト サブタイプに用意されている実装に委任されます。 異なる集計レベル間で状態を保持されるメカニズムとして、すべてのレベルのプロジェクト サブタイプに IPersistXMLFragment を実装し、ビルドに関係ない XML データをプロジェクト ファイルに保持します。 詳細については、「MSBuild プロジェクト ファイルでのデータの保持」を参照してください。 IInternalExtenderProvider は、プロジェクト サブタイプからオートメーション エクステンダーを取得するメカニズムとして実装されています。

次の図は、オートメーション エクステンダーの実装、その中でも特に、ベース プロジェクト システムを拡張するためにプロジェクト サブタイプによって使用されるプロジェクト構成参照オブジェクトに焦点を当てています。

VS Project Flavor Auto Extender graphic

プロジェクト サブタイプを使用して、オートメーション オブジェクト モデルを拡張することにより、ベース プロジェクト システムをさらに拡張できます。 これらは DTE オートメーション オブジェクトの一部として定義され、Project オブジェクト、ProjectItem オブジェクト、Configuration オブジェクトを拡張するために使用されます。 詳細については、「ベース プロジェクトのオブジェクト モデルの拡張」を参照してください。

複数レベルの集計

下位レベルのプロジェクト サブタイプをラップするプロジェクト サブタイプの実装は、内部のプロジェクト サブタイプが適切に機能するように協調的にプログラムする必要があります。 プログラミングの役割の一覧は次のとおりです。

  • 内側のサブタイプをラップしているプロジェクト サブタイプの IPersistXMLFragment の実装は、LoadSave の両メソッドについて、内側のプロジェクト サブタイプの IPersistXMLFragment の実装に委任する必要があります。

  • ラッパー プロジェクト サブタイプの IInternalExtenderProvider の実装は、その内側のプロジェクト サブタイプの実装に委任する必要があります。 特に、GetExtenderNames の実装の場合、内側のプロジェクト サブタイプから名前の文字列を取得してから、エクステンダーとして追加する文字列を連結する必要があります。

  • ラッパー プロジェクト サブタイプの IVsProjectCfgProvider の実装の場合、内側のプロジェクト サブタイプの IVsProjectFlavorCfg オブジェクトのインスタンスを作成し、プライベート デリゲートとして保持する必要があります。これは、ラッパー プロジェクト サブタイプの構成オブジェクトの存在を直接認識しているのは、ベース プロジェクトのプロジェクト構成オブジェクトのみだからです。 外側のプロジェクト サブタイプにより、まず直接処理する構成インターフェイスが選択され、残りは内側のプロジェクト サブタイプの get_CfgType の実装に委任されます。

サポート インターフェイス

ベース プロジェクトにより、プロジェクト サブタイプから追加されたサポート インターフェイスへの呼び出しが委任され、その実装のさまざまな側面が拡張されます。 これには、プロジェクト構成オブジェクトとさまざまなプロパティ ブラウザー オブジェクトの拡張が含まれます。 これらのインターフェイスを取得するには、最も外側にあるプロジェクト サブタイプ アグリゲーターの punkOuter (IUnknown へのポインター) に対して QueryInterface を呼び出します。

インターフェイス プロジェクト サブタイプ
IVsProjectFlavorCfg プロジェクト サブタイプを使用すると、次のことができるようになります。

- IVsDeployableProjectCfg の実装を用意します。
- プロジェクト サブタイプにより、独自の IVsDebuggableProjectCfg の実装を用意できるようにすることで、デバッガーの起動を制御します。
- QueryDebugLaunch の実装で DBGLAUNCH_DesignTimeExprEval のケースを適切に処理することにより、デザイン時の式の評価を無効にします。
IInternalExtenderProvider プロジェクト サブタイプを使用すると、次のことができるようになります。

- プロジェクトの VSHPROPID_BrowseObject を拡張して、プロジェクトの構成に依存しないプロパティを追加または削除できるようにします。
- プロジェクトのプロジェクト オートメーション オブジェクト (VSHPROPID_ExtObject) を拡張します。

上記のプロパティ値は、__VSHPROPID2 の列挙から取得されます。
IVsCfgBrowseObject プロジェクト構成参照オブジェクトを指定して、プロジェクト サブタイプを IVsCfg オブジェクトにマップし直すことができます。
IVsBrowseObject プロジェクト構成参照オブジェクトを指定して、プロジェクト サブタイプを IVsHierarchy または VSITEMID オブジェクトにマップし直すことができます。
IPersistXMLFragment プロジェクト サブタイプを使用して、任意の XML 構造化データをプロジェクト ファイル (.vbproj または .csproj) に保持できるようにします。 このデータは MSBuild には表示されません。
IVsBuildPropertyStorage プロジェクト サブタイプを使用すると、次のことができるようになります。

- 保持する新しい MSBuild プロパティを追加します。
- MSBuild から不要なプロパティを削除します。
- MSBuild プロパティの現在の値のクエリを実行します。
- MSBuild プロパティの現在の値を変更します。

関連項目