レイヤー図へのカスタム アーキテクチャ検証の追加
Visual Studio Ultimate および Visual Studio Premium では、Visual Studio プロジェクトのソース コードをレイヤー モデルと対比して検証し、ソース コードがレイヤー図の依存関係に準拠していることを確認できます。標準の検証アルゴリズムがありますが、Visual Studio Ultimate と Visual Studio Premiumの独自の検証拡張機能を定義できます。
ユーザーがレイヤー図で [アーキテクチャの検証] を選択すると、標準の検証メソッドが呼び出された後、インストールされている検証拡張機能が呼び出されます。
[!メモ]
レイヤー図での検証は、UML 図での検証と同じではありません。レイヤー図での主要な目的は、図と、ソリューションの他の部分のプログラム コードを比較することです。
レイヤー検証拡張機能を Visual Studio Integration Extension (VSIX) にパッケージ化し、他の Visual Studio Ultimate ユーザーに配布できます。検証機能は、単独で VSIX に配置することも、他の拡張機能と組み合わせて同じ VSIX に含めることもできます。検証コントロールのコードは、他の拡張機能と同じプロジェクトではなく、専用の Visual Studio プロジェクトで作成する必要があります。
注意 |
---|
検証プロジェクトを作成したら、を コード例 このトピックの最後にコピーし、独自のニーズにそれを編集します。 |
要件
Visual Studio Ultimate
Visual Studio SDK
Visual Studio Visualization and Modeling SDK
新しい VSIX でレイヤー検証コントロールを定義する
最も簡単に検証コントロールを作成するには、プロジェクト テンプレートを使用します。この方法では、コードと VSIX マニフェストが同じプロジェクトに配置されます。
プロジェクト テンプレートを使用して拡張機能を定義するには
[ファイル] メニューの [新しいプロジェクト] を使用して、新しいソリューションにプロジェクトを作成します。
[新しいプロジェクト] ダイアログ ボックスの [モデリング プロジェクト] で、[Layer Designer Validation Extension] (レイヤー デザイナー検証拡張機能) をクリックします。
このテンプレートでは、小さい例を含むプロジェクトが作成されます。
注意 テンプレートが正しく機能:
省略可能な引数 errorSourceNodes と errorTargetNodesを削除 LogValidationError への編集を呼び出します。
カスタム プロパティを使用している場合は、レイヤー図へのカスタム プロパティの追加) で示された更新を追加します。モデルまたはソリューションを開く前に、アーキテクチャ エクスプローラーを開くには。
コードを編集して検証を定義します。詳細については、「検証のプログラミング」を参照してください。
拡張機能をテストするには、「レイヤー検証のデバッグ」を参照してください。
[!メモ]
メソッドは特定の状況においてのみ呼び出され、ブレークポイントは自動的には動作しません。詳細については、「レイヤー検証のデバッグ」を参照してください。
Visual Studio のメイン インスタンスまたは別のコンピューターに拡張機能をインストールするには、bin\* で .vsix ファイルを探します。このファイルをインストール先のコンピューターにコピーして、ダブルクリックします。拡張機能をアンインストールするには、[ツール] メニューの [拡張機能マネージャー] を使用します。
レイヤー検証コントロールを別の VSIX に追加する
レイヤー検証コントロール、コマンド、および他の拡張機能を含む 1 つの VSIX を作成する場合は、VSIX を定義するプロジェクトとハンドラー用のプロジェクトを別にすることをお勧めします。他の種類のモデリング拡張機能については、「UML モデルと図の拡張」を参照してください。
レイヤー検証を別の VSIX に追加するには
新規または既存の Visual Studio Ultimate ソリューションでクラス ライブラリ プロジェクトを作成します。[新しいプロジェクト] ダイアログ ボックスで、[Visual C#] をクリックし、[クラス ライブラリ] をクリックします。このプロジェクトには、レイヤー検証クラスが含められます。
ソリューションで VSIX プロジェクトを特定または作成します。VSIX プロジェクトには、source.extension.vsixmanifest という名前のファイルが含まれます。VSIX プロジェクトを追加する必要がある場合は、以下の手順に従います。
[新しいプロジェクト] のダイアログ ボックスで、[Visual C#]、[機能拡張]、[VSIX プロジェクト] を選択します。
VSIX プロジェクトのショートカット メニューの [ソリューション エクスプローラー] では、[スタートアップ プロジェクトに設定]。
source.extension.vsixmanifestでは、[資産] の下に、MEF コンポーネントとしてレイヤー検証プロジェクトを追加します:
[新規作成] をクリックします。
[新しい資産の追加] のダイアログ ボックスで、を設定します:
[種類] = [Microsoft.VisualStudio.MefComponent]
[ソース] = [現在のソリューション内のプロジェクト]
プロジェクト = 独自の検証コントロール プロジェクト
また、レイヤー検証として追加する必要があります:
[新規作成] をクリックします。
[新しい資産の追加] のダイアログ ボックスで、を設定します:
[種類] = [Microsoft.VisualStudio.ArchitectureTools.Layer.Validator]。これは、ボックスの一覧の選択項目の 1 つがではありません。キーボードから入力する必要があります。
[ソース] = [現在のソリューション内のプロジェクト]
プロジェクト = 独自の検証コントロール プロジェクト
レイヤー検証プロジェクトに戻り、次のプロジェクト参照を追加します。
Reference
実行できる操作
Microsoft.VisualStudio.GraphModel.dll
アーキテクチャ グラフを読み取る
Microsoft.VisualStudio.ArchitectureTools.Extensibility.CodeSchema.dll
レイヤーと関連付けられているコード DOM を読み取る
Microsoft.VisualStudio.ArchitectureTools.Extensibility.Layer.dll
レイヤー モデルを読み取る
Microsoft.VisualStudio.ArchitectureTools.Extensibility
図形と図を読み取って更新する
System.ComponentModel.Composition
MEF (Managed Extensibility Framework) を使用して検証コンポーネントを定義する
Microsoft.VisualStudio.Modeling.Sdk.11.0
モデリング拡張機能を定義する
独自の検証のコードを含む検証コントロール ライブラリ プロジェクトのクラス ファイル、このトピックの最後にあるコード例をコピーします。詳細については、「検証のプログラミング」を参照してください。
拡張機能をテストするには、「レイヤー検証のデバッグ」を参照してください。
[!メモ]
メソッドは特定の状況においてのみ呼び出され、ブレークポイントは自動的には動作しません。詳細については、「レイヤー検証のデバッグ」を参照してください。
Visual Studio のメイン インスタンスまたは別のコンピューターに VSIX をインストールするには、VSIX プロジェクトの bin ディレクトリで .vsix ファイルを探します。このファイルを、VSIX をインストールするコンピューターにコピーします。Windows エクスプローラーで、VSIX ファイルをダブルクリックします。(Windows 8.のファイル エクスプローラー)
拡張機能をアンインストールするには、[ツール] メニューの [拡張機能マネージャー] を使用します。
検証のプログラミング
レイヤー検証拡張機能を定義するには、以下の特性を備えたクラスを定義します。
宣言の全体的な形式を次に示します。
using System.ComponentModel.Composition; using Microsoft.VisualStudio.ArchitectureTools.Extensibility.CodeSchema; using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Layer; using Microsoft.VisualStudio.GraphModel; ... [Export(typeof(IValidateArchitectureExtension))] public partial class Validator1Extension : IValidateArchitectureExtension { public void ValidateArchitecture(Graph graph) { GraphSchema schema = graph.DocumentSchema; ... } }
エラーを検出したときは、LogValidationError() を使用して報告できます。
注意 LogValidationErrorの省略可能なパラメーターを使用しないでください。
ユーザーが [アーキテクチャの検証] を実行すると、レイヤーのランタイム システムがレイヤーとその成果物を分析して、グラフを生成します。グラフは 4 つの部分で構成されます。
Visual Studio ソリューションのレイヤー モデルは、グラフではノードとリンクとして表されます。
ソリューションで定義されているコード、プロジェクト アイテム、および他の成果物は、ノードおよび分析システムによって検出された依存関係を示すリンクとして表されます。
レイヤー ノードからコード成果物ノードへのリンク。
検証コントロールによって検出されたエラーを表すノード。
グラフが作成されると、標準の検証メソッドが呼び出されます。これが完了すると、インストールされているすべての拡張検証メソッドが、不定の順序で呼び出されます。グラフを渡された各 ValidateArchitecture メソッドは、グラフをスキャンし、検出したエラーを報告します。
[!メモ]
これは、UML 図に適用される検証プロセスと同じではなく、特定領域言語で使用できる検証プロセスとも同じではありません。
検証メソッドでは、レイヤー モデルまたは検証対象のコードを変更することはできません。
グラフ モデルは、Microsoft.VisualStudio.GraphModel で定義されています。そのプリンシパル クラスは、GraphNode および GraphLink です。
各ノードおよび各リンクには 1 つ以上のカテゴリがあり、それぞれが表す要素または関係の種類が指定されています。標準的なグラフのノードには以下のカテゴリがあります。
Dsl.LayerModel
Dsl.Layer
Dsl.Reference
CodeSchema_Type
CodeSchema_Namespace
CodeSchema_Type
CodeSchema_Method
CodeSchema_Field
CodeSchema_Property
レイヤーからコード内の要素へのリンクのカテゴリは "Represents" です。
検証のデバッグ
レイヤー検証拡張機能をデバッグするには、Ctrl キーを押しながら F5 キーを押します。Visual Studio の実験用のインスタンスが開きます。このインスタンスで、レイヤー モデルを開くか作成します。このモデルは、コードと関連付けられている必要があり、少なくとも 1 つの依存関係を含む必要があります。
依存関係を含むソリューションでのテスト
以下の特性が存在していない限り、検証は実行されません。
レイヤー図に、少なくとも 1 つの依存関係リンクが存在する。
コード要素と関連付けられたレイヤーがモデルに存在する。
初めて Visual Studio の実験用インスタンスを起動して検証拡張機能をテストするときは、これらの特性を備えたソリューションを開くか作成します。
アーキテクチャを検証する前に [ソリューションのクリーン] を実行する
検証コードを更新したときは常に、検証コマンドをテストする前に、実験用ソリューションで [ビルド] メニューの [ソリューションのクリーン] を使用します。これは、検証の結果がキャッシュされているために必要です。テスト レイヤー図またはそのコードが更新されていない場合は、検証メソッドは実行されません。
デバッガーを明示的に起動する
検証は別のプロセスで実行されます。したがって、検証メソッドのブレークポイントはトリガーされません。検証が開始したら、デバッガーをプロセスに明示的にアタッチする必要があります。
デバッガーを検証プロセスにアタッチするには、検証メソッドの先頭に System.Diagnostics.Debugger.Launch() の呼び出しを挿入します。デバッグ ダイアログ ボックスが表示されたら、Visual Studio のメイン インスタンスを選択します。
または、System.Windows.Forms.MessageBox.Show() の呼び出しを挿入してもかまいません。メッセージ ボックスが表示されたら、Visual Studio のと [デバッグ] のメニューのをクリック [プロセスにアタッチ] のメイン インスタンスに移動します。Graphcmd.exeというプロセスを選択します。
常に、Ctrl キーを押しながら F5 キーを押して ([デバッグなしで開始]) 実験用インスタンスを起動します。
検証拡張機能を配置する
Visual Studio Ultimate または Visual Studio Premium がインストールされているコンピューターに検証拡張機能をインストールするには、対象のコンピューターで VSIX ファイルを開きます。Team Foundation ビルド がインストールされているコンピューターにインストールするには、VSIX の内容を Extensions フォルダーに手動で抽出する必要があります。詳細については、「レイヤー モデリング拡張機能の配置」を参照してください。
コード例
using System;
using System.ComponentModel.Composition;
using System.Globalization;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.ArchitectureTools.Extensibility.CodeSchema;
using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Layer;
using Microsoft.VisualStudio.GraphModel;
namespace Validator3
{
[Export(typeof(IValidateArchitectureExtension))]
public partial class Validator3Extension : IValidateArchitectureExtension
{
/// <summary>
/// Validate the architecture
/// </summary>
/// <param name="graph">The graph</param>
public void ValidateArchitecture(Graph graph)
{
if (graph == null) throw new ArgumentNullException("graph");
// Uncomment the line below to debug this extension during validation
// System.Windows.Forms.MessageBox.Show("Attach 2 to GraphCmd.exe with process id " + System.Diagnostics.Process.GetCurrentProcess().Id);
// Get all layers on the diagram
foreach (GraphNode layer in graph.Nodes.GetByCategory("Dsl.Layer"))
{
System.Threading.Thread.Sleep(100);
// Get the required regex property from the layer node
string regexPattern = "^[a-zA-Z]+$"; //layer[customPropertyCategory] as string;
if (!string.IsNullOrEmpty(regexPattern))
{
Regex regEx = new Regex(regexPattern);
// Get all referenced types in this layer including those from nested layers so each
// type is validated against all containing layer constraints.
foreach (GraphNode containedType in layer.FindDescendants().Where(node => node.HasCategory("CodeSchema_Type")))
{
// Check the type name against the required regex
CodeGraphNodeIdBuilder builder = new CodeGraphNodeIdBuilder(containedType.Id, graph);
string typeName = builder.Type.Name;
if (!regEx.IsMatch(typeName))
{
// Log an error
string message = string.Format(CultureInfo.CurrentCulture, Resources.InvalidTypeNameMessage, typeName);
this.LogValidationError(graph, typeName + "TypeNameError", message, GraphErrorLevel.Error, layer);
}
}
}
}
}
}
}