在圖層圖表中加入自訂架構驗證
在 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] (圖層設計工具驗證擴充功能)。
此範本就會建立包含小型範例的專案。
警告 讓範本正常運作:
in 要移除選擇性引數的編譯 LogValidationError 呼叫 errorSourceNodes 和 errorTargetNodes。
如果您使用自訂屬性,請使用 將自訂屬性加入至圖層圖表中所述的更新。此外,開啟架構總管,在中開啟模型方案。
編輯程式碼以定義驗證。如需詳細資訊,請參閱驗證程式設計。
若要測試擴充功能,請參閱偵錯圖層驗證。
注意事項 您的方法只會在特定情況下呼叫,而且中斷點將無法自動運作。如需詳細資訊,請參閱偵錯圖層驗證。
若要在 Visual Studio 的主要執行個體或其他電腦上安裝擴充功能,請在 bin\* 中尋找 .vsix 檔案。將它複製到您想要安裝的目標電腦,然後按兩下該檔案。若要解除安裝此元件,請使用 [工具] 功能表上的 [擴充管理員]。
將圖層驗證程式加入至個別 VSIX
如果您想要建立包含圖層驗證程式、命令和其他擴充功能的單一 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]。這不是其中一個下拉式清單的選項。您必須輸入它從鍵盤。
來源 = 在目前方案中的專案
[專案] = 您的驗證程式專案
返回圖層驗證專案,然後加入下列專案參考:
參考資料
這可讓您執行的項目
Microsoft.VisualStudio.GraphModel.dll
讀取架構圖形
Microsoft.VisualStudio.ArchitectureTools.Extensibility.CodeSchema.dll
讀取與圖層相關聯的程式碼 DOM
Microsoft.VisualStudio.ArchitectureTools.Extensibility.Layer.dll
讀取圖層模型
Microsoft.VisualStudio.ArchitectureTools.Extensibility
讀取和更新圖案與圖表
System.ComponentModel.Composition
使用 Managed Extensibility Framework (MEF) 定義驗證元件
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選擇性參數。
當使用者叫用 [驗證架構] 功能表命令時,圖層執行階段系統就會分析圖層及其成品以產生圖形。此圖形具有四個部分:
Visual Studio 方案的圖層模型,這些模型會在圖形中表示成節點和連結。
定義於方案中而且表示成節點的程式碼、專案項目和其他成品,以及代表分析處理序所發現之相依性的連結。
從圖層節點連至程式碼成品節點的連結。
代表驗證程式所發現之錯誤的節點。
當系統已經建構圖形時,就會呼叫標準驗證方法。完成此作業之後,系統就會按照未指定的順序呼叫任何已安裝的擴充功能驗證方法。此圖形會傳遞給每個 ValidateArchitecture 方法,以便掃描圖形並報告它所發現的任何錯誤。
注意事項 |
---|
這項作業與套用至 UML 圖表的驗證處理序不同,而且與可用於網域指定之語言的驗證處理序不同。 |
驗證方法不應該變更所驗證的圖層模型或程式碼。
圖形模型定義於 Microsoft.VisualStudio.GraphModel 中。其主體類別為 GraphNode 和 GraphLink。
每個節點和每個連結都具有一個或多個分類,這些分類會指定它所代表的項目或關聯性類型。一般圖形的節點具有下列分類:
Dsl.LayerModel
Dsl.Layer
Dsl.Reference
CodeSchema_Type
CodeSchema_Namespace
CodeSchema_Type
CodeSchema_Method
CodeSchema_Field
CodeSchema_Property
從圖層連至程式碼中項目的連結具有 "Represents" 分類。
偵錯驗證
若要偵錯圖層驗證擴充功能,請按下 CTRL+F5。Visual Studio 的實驗執行個體隨即開啟。在此執行個體中,開啟或建立圖層模型。這個模型必須與程式碼相關聯,而且至少必須具有一個相依性。
使用包含相依性的方案進行測試
除非下列特性存在,否則系統不會執行驗證:
圖層圖表至少具有一個相依性連結。
模型具有與程式碼項目相關聯的圖層。
當您第一次啟動 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 Build 的電腦上安裝,您必須將 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);
}
}
}
}
}
}
}