Postupy: Definování omezení ověření pro modely UML
V Visual Studio Ultimate můžete definovat omezení ověření, která testují, zda model splňuje zadanou podmínku.Můžete například definovat omezení a ujistit se, že uživatel nevytvoří smyčku vztahů dědičnosti.Omezení je vyvoláno, když se uživatel pokusí otevřít nebo uložit model, a může být vyvoláno také ručně.Pokud omezení selže, chybová zpráva, která definujete, je přidána do okna chyby.Můžete zabalit tato omezení do rozšíření integrace Visual Studio (VSIX) a distribuovat ostatním uživatelům Visual Studio Ultimate.
Můžete také definovat omezení, která ověřují model proti externím prostředkům, jako je například databáze.
[!POZNÁMKA]
Pokud chcete ověřit kód programu proti diagramu vrstvy, viz Přidání ověření vlastní architektury do diagramů vrstev.
Požadavky
Visual Studio SDK, kterou lze získat z Galerie sady Visual Studio.
Visual Studio Visualization and Modeling SDK, kterou lze získat z Galerie kódu Visual Studio Visualization and Modeling SDK.
Použití omezení ověření
Omezení ověření jsou použita ve třech případech: při uložení modelu; při otevření modelu; a po klepnutí na možnost Ověřit model UML v nabídce Architektura.V každém případě pouze ta omezení, která byla definována pro tento případ, budou použita, i když obvykle definujete každé omezení, které chcete použít ve více než jednom případě.
Chyby ověření jsou hlášeny v okně chyb Visual Studio a poklepáním na chybu můžete vybrat prvky modelu, které jsou chybné.
Další informace o použití ověřování naleznete v tématu Ověření modelu UML.
Definování ověřování rozšíření
Chcete-li vytvořit rozšíření ověření pro UML designer, musíte vytvořit třídu, která definuje omezení ověření, a vložit tuto třídu do VSIX.VSIX funguje jako kontejner, který může omezení nainstalovat.Existují dva alternativní způsoby definování rozšíření ověření:
Vytvořte rozšíření ověřování ve vlastním souboru VSIX pomocí šablony projektu. Toto je rychlejší metoda.Pokud nechcete, aby vaše omezení ověření kombinovat s jinými typy rozšíření například příkazy nabídek, vlastními položkami panelu nástrojů nebo obslužnými rutinami gest, použijte ji.V jedné třídě lze definovat několik omezení.
Vytvoření samostatné třídy ověření a projektů VSIX. Tuto metodu použijte, pokud chcete sloučit několik typů rozšíření do stejného VSIX.Například pokud váš příkaz nabídky očekává, že model bude dodržovat zvláštní omezení, můžete jej vložit do stejného VSIX jako metodu ověřování.
Vytvoření rozšíření ověření ve vlastním souboru VSIX
V dialogovém okně Nový projekt, v části Modelování projektů vyberte Rozšíření ověřování.
Otevřete soubor .cs v novém projektu a upravte třídu pro implementaci omezení ověření.
Další informace viz Implementace omezení ověřování.
Důležité Ujistěte se, že vaše soubory .cs obsahují následující příkaz using:
using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Uml;
Definováním nových metod můžete přidat další omezení.K identifikaci metody jako metody ověření musí být označena atributy stejným způsobem jako původní ověřovací metoda.
Otestujte omezení stisknutím klávesy F5.Další informace naleznete v tématu Provedení ověření.
Nainstalujte příkaz nabídky v jiném počítači zkopírováním souboru bin\*\*.vsix, který je sestaven projektem.Další informace viz Instalace omezení ověřování.
Když přidáte další soubory .cs, budete obvykle potřebovat následující příkazy using:
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Uml;
using Microsoft.VisualStudio.Modeling.Validation;
using Microsoft.VisualStudio.Uml.Classes;
Zde je alternativní postup:
Vytvoření zvláštního omezení ověření v projektu knihovny tříd
Vytvořte projekt knihovny tříd a přidejte jej do existujícího VSIX řešení nebo vytvořte nové řešení.
V nabídce Soubor zvolte položku Nový, Projekt.
V části Nainstalované šablony rozbalte položku Visual C# nebo Visual Basic a potom v prostředním sloupci zvolte možnost Knihovna tříd.
Vytvořte projekt VSIX, pokud ho vaše řešení ještě neobsahuje:
V Průzkumníku řešení v místní nabídce řešení zvolte Přidat, Nový projekt.
V části Nainstalované šablony rozbalte možnost Visual C# nebo Visual Basic a potom vyberte možnost Rozšiřitelnost.V prostředním sloupci klikněte na Projekt VSIX.
Nastavte projekt VSIX jako projekt po spuštění pro řešení.
- V Průzkumníku řešení v místní nabídce projektu VSIX zvolte Nastavit jako projekt po spuštění.
V source.extension.vsixmanifest, v části Obsah přidejte projekt knihovny tříd jako komponentu MEF:
Na kartě MetaData nastavte název souboru VSIX.
Na kartě Cíle instalace nastavte sady Visual Studio Ultimate a Premium jako cíle.
Na kartě Aktiva vyberte možnost Nové a v dialogovém okně nastavte:
Typ = Komponenta MEF
Zdroj = Projekt v aktuálním řešení.
Projekt = Your class library project
Definice třídy validace
Tuto proceduru nepotřebujete, pokud jste vytvořili třídu ověřování s vlastním souborem VSIX z šablony projektu ověřování.
V ověření projektu třídy přidejte odkazy na následující sestavení .NET:
Microsoft.VisualStudio.Modeling.Sdk.12.0
Microsoft.VisualStudio.ArchitectureTools.Extensibility.Uml
Microsoft.VisualStudio.Uml.Interfaces
System.ComponentModel.Composition
Přidejte soubor do projektu knihovny tříd obsahujícího kód, který je podobný následujícímu příkladu.
Každé omezení ověření je součástí metody, která je označena určitým atributem.Metoda přijímá parametr typu prvku modelu.Při vyvolání ověření, rozhraní ověřování použije každou metodu ověřování na každý prvek modelu, který odpovídá jeho typu parametru.
Tyto metody můžete umístit do libovolných tříd a oborů názvů.Změňte je dle požadavků.
using System.Collections.Generic; using System.ComponentModel.Composition; using System.Linq; using Microsoft.VisualStudio.Modeling.Validation; using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Uml; using Microsoft.VisualStudio.Uml.Classes; // You might also need the other Microsoft.VisualStudio.Uml namespaces. namespace Validation { public class MyValidationExtensions { // SAMPLE VALIDATION METHOD. // All validation methods have the following attributes. [Export(typeof(System.Action<ValidationContext, object>))] [ValidationMethod( ValidationCategories.Save | ValidationCategories.Open | ValidationCategories.Menu)] public void ValidateClassNames (ValidationContext context, // This type determines what elements // will be validated by this method: IClass elementToValidate) { // A validation method should not change the model. List<string> attributeNames = new List<string>(); foreach (IProperty attribute in elementToValidate.OwnedAttributes) { string name = attribute.Name; if (!string.IsNullOrEmpty(name) && attributeNames.Contains(name)) { context.LogError( string.Format("Duplicate attribute name '{0}' in class {1}", name, elementToValidate.Name), "001", elementToValidate); } attributeNames.Add(name); } } // Add more validation methods for different element types. } }
Provádění ověření omezení
Pro účely testování spusťte metodu ověřování v režimu ladění.
Testování omezení ověření
Stiskněte klávesu F5 nebo v nabídce Ladit zvolte Spustit ladění.
Spustí se experimentální instance aplikace Visual Studio.
Poradce při potížích: Pokud se nová aplikace Visual Studio nespustí:
Pokud máte více než jeden projekt, ujistěte se, že projekt VSIX je nastaven jako projekt při spuštění řešení.
V Průzkumníku řešení v místní nabídce startupu nebo projektu zvolte Vlastnosti.V editoru vlastností projektu zvolte kartu Ladění.Ujistěte se, že řetězec v poli Spustit externí program je úplný název cesty Visual Studio, obvykle:
C:\Program Files\Microsoft Visual Studio 12.0\Common7\IDE\devenv.exe
V experimentální instanci aplikace Visual Studio otevřete nebo vytvořte projekt modelování a otevřete nebo vytvořte diagram modelování.
Nastavení testu pro testovací omezení uvedené v předchozí části:
Otevřete diagram třídy.
Vytvořte třídu a přidejte dva atributy, které mají stejný název.
V místní nabídce kdekoli v diagramu zvolte možnost Ověřit.
Jakékoli chyby v modelu budou hlášeny v okně chyb.
Poklepejte na zprávu o chybě.Pokud jsou prvky uvedené v sestavě zobrazeny na obrazovce, budou zvýrazněny.
Poradce při potížích: Pokud se příkaz Ověřit v nabídce nezobrazí, zkontrolujte, zda:
Projekt ověření nabídky je uveden jako komponenta MEF na kartě Aktiva v source.extensions.manifest v projektu VSIX.
Správné vlastnosti Export a ValidationMethod jsou přiřazeny k ověřovacím metodám.
ValidationCategories.Menu je součástí argumentu pro atribut ValidationMethod a je tvořena jinými hodnotami pomocí logického OR (|).
Parametry všech vlastností Import a Export jsou platné.
Vyhodnocování omezení
Metoda ověření by měla určit, zda má omezení ověření, které chcete použít, hodnotu true nebo false.Pokud true, neměla by provést žádnou akci.Pokud false, měli byste nahlásit chybu pomocí metod poskytovaných parametrem ValidationContext.
[!POZNÁMKA]
Metody ověřování by neměly měnit model.Neexistuje záruka, kdy a v jakém pořadí budou omezení provedena.Pokud musíte předat informace mezi po sobě jdoucích spuštěních metody ověřování v rámci ověřovacího běhu, můžete použít kontext mezipaměti popsaný v části Koordinace více ověření.
Například pokud chcete zajistit, že každý typ (třída, rozhraní nebo výčet) má název, který je dlouhý alespoň tři znaky, můžete použít tuto metodu:
public void ValidateTypeName(ValidationContext context, IType type)
{
if (!string.IsNullOrEmpty(type.Name) && type.Name.Length < 3)
{
context.LogError(
string.Format("Type name {0} is too short", type.Name),
"001", type);
}
}
Viz Programování s rozhraním API UML pro informace o metodách a typech, které můžete použít k procházení a čtení modelu.
O metodách omezení ověřování
Každé omezení ověření je definováno metodou v následujícím formátu:
[Export(typeof(System.Action<ValidationContext, object>))]
[ValidationMethod(ValidationCategories.Save
| ValidationCategories.Menu
| ValidationCategories.Open)]
public void ValidateSomething
(ValidationContext context, IClassifier elementToValidate)
{...}
Atributy a parametry každé metody ověření jsou:
[Export(typeof(System.Action <ValidationContext, object>))] |
Definuje metodu jako omezení ověřování pomocí Managed Extensibility Framework (MEF). |
[ValidationMethod (ValidationCategories.Menu)] |
Určuje, kdy bude ověření provedeno.Použijte bitový operátor OR (|), pokud chcete zkombinovat více než jednu možnost. Menu = vyvoláno nabídkou Ověřit. Save = vyvolána při uložení modelu. Open = vyvolána při otevření modelu.Load = vyvolán při uložení modelu, ale preventivně uživatele upozorní, že nemusí být možné model znovu otevřít.Také voláno při načítání před analýzou modelu. |
public void ValidateSomething (ValidationContext context, IElement element) |
Nahraďte druhý parametr IElement typem prvku, na který chcete, aby omezení platilo.Metoda omezení bude vyvolána na všechny prvky v zadaném typu. Název metody není důležitý. |
Můžete definovat, kolik ověřovacích metod chcete s různými typy ve druhém parametru.Při vyvolání ověření každá metoda ověřování bude volána na každý prvek modelu, který odpovídá typu parametru.
Oznamování chyb ověřování
Chcete-li vytvořit zprávu o chybách, použijte metody poskytované ValidationContext:
context.LogError("error string", errorCode, elementsWithError);
"error string" se zobrazí v seznamu chyb Visual Studio
errorCode je řetězec, který by měl být jedinečným identifikátorem chyby
elementsWithError identifikuje prvky v modelu.Když uživatel poklepe na sestavu chyby, bude vybrán obrazec představující tento prvek.
LogError(),LogWarning() a LogMessage() umísťují zprávy v různých částech seznamu chybových zpráv.
Jak jsou použity metody ověřování
Ověření se aplikuje na každý prvek v modelu, včetně vztahů a částí větších prvků, jako jsou atributy třídy a parametry operace.
Každá metoda ověřování se aplikuje na každý prvek, který odpovídá typu v jejím druhém parametru.To znamená, že například pokud definujete metodu ověření s druhým parametrem IUseCase a jinou s jeho nadtypem IElement, pak obě tyto metody budou použity na každý případ použití v modelu.
Hierarchie typů je shrnuta v části Typy prvků modelu.
Můžete také získat přístup k prvků následujícími vztahy.Například, pokud chcete definovat ověřovací metodu na IClass, mohli byste projít jeho vlastněnými vlastnostmi:
public void ValidateTypeName(ValidationContext context, IClass c)
{
foreach (IProperty property in c.OwnedAttributes)
{
if (property.Name.Length < 3)
{
context.LogError(
string.Format(
"Property name {0} is too short",
property.Name),
"001", property);
}
}
}
Vytváření ověřovací metody na modelu
Pokud chcete, aby bylo zajištěno, že metoda ověření je volána přesně jednou při každém spuštění ověřování, můžete ověřit IModel:
using Microsoft.VisualStudio.Uml.AuxiliaryConstructs; ...
[Export(typeof(System.Action<ValidationContext, object>))]
[ValidationMethod(ValidationCategories.Menu)]
public void ValidateModel(ValidationContext context, IModel model)
{ foreach (IElement element in model.OwnedElements)
{ ...
Ověřování tvarů a diagramů
Metody ověřování nejsou vyvolány na prvky zobrazení jako diagramy a tvary, protože primárním účelem metod ověření je ověřovat model.Pomocí kontextu diagramu však můžete přistupovat k aktuálnímu diagramu.
Ve vaší třídě ověření deklarujte DiagramContext jako importovanou vlastnost:
using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Presentation;
...
[Import]
public IDiagramContext DiagramContext { get; set; }
V metodě ověření můžete použít DiagramContext pro přístup k aktuálnímu diagramu fokusu, pokud existuje:
[Export(typeof(System.Action<ValidationContext, object>))]
[ValidationMethod(ValidationCategories.Menu)]
public void ValidateModel(ValidationContext context, IModel model)
{
IDiagram focusDiagram = DiagramContext.CurrentDiagram;
if (focusDiagram != null)
{
foreach (IShape<IUseCase> useCaseShape in
focusDiagram.GetChildShapes<IUseCase>())
{ ...
Chcete-li zaprotokolovat chybu, musíte získat prvek modelu, který tvar představuje, protože nemůžete předat tvar do LogError:
IUseCase useCase = useCaseShape.Element;
context.LogError(... , usecase);
Koordinace více ověřování
Když je ověření vyvoláno, například uživatelem v nabídce diagramu, každá metoda ověřování je použita na každý prvek modelu.To znamená, že v jednom vyvolání rozhraní ověření lze stejnou metodu použít mnohokrát na různé prvky.
To představuje problém pro ověření, která se zabývají vztahy mezi prvky.Můžete například napsat ověření, které začíná od, řekněme, případu použití a překračuje vztahy include k ověření, že neexistují žádné smyčky.Ale když metoda platí pro každý případ použití v modelu, který má mnoho odkazů include, je pravděpodobné, že opakovaně zpracuje stejné oblasti modelu.
Aby se předešlo této situaci, existuje mezipaměť kontextu, ve které se uchovají informace během procesu ověřování.Můžete ji použít k předávání informací mezi různými běhy metod ověřování.Například můžete uložit seznam prvků, které již byly zpracovány v tomto spuštění ověřování.Mezipaměť je vytvořena na začátku každého běhu ověřování a nelze ji použít k předávání informací mezi různými běhy ověřování.
context.SetCacheValue<T> (name, value) |
Uložit hodnotu |
context.TryGetCacheValue<T> (name, out value) |
Získat hodnotu.Pokud je úspěšná, vrátí hodnotu pravda. |
context.GetValue<T>(name) |
Získat hodnotu. |
Context.GetValue<T>() |
Získat hodnotu zadaného typu. |
Instalace a odinstalace rozšíření
Je možné nainstalovat rozšíření Visual Studio ve vašem počítači i v jiných počítačích.
Instalace rozšíření
V počítači vyhledejte soubor .vsix, který byl vytvořen vaším projektem VSIX.
V Průzkumníku řešení, v místní nabídce projektu VSIX, zvolte Otevřít složku v Průzkumníku Windows.
Vyhledejte soubor bin\*\YourProject.vsix
Zkopírujte soubor .vsix do cílového počítače, ve kterém chcete nainstalovat rozšíření.Může to být váš vlastní počítač nebo jiný.
- Cílový počítač musí mít jednu z edic systému Visual Studio, kterou jste zadali v source.extension.vsixmanifest.
V cílovém počítači otevřete soubor .vsix.
Instalační služba rozšíření sady Visual Studio se otevře a nainstaluje rozšíření.
Spusťte nebo restartujte aplikaci Visual Studio.
Odinstalace rozšíření
V nabídce Nástroje zvolte tlačítko Správce rozšíření.
Rozbalte nainstalována rozšíření.
Vyberte rozšíření a poté vyberte možnost Odinstalovat.
Jen zřídka se chybné rozšíření nedokáže načíst a vytvoří sestavu v okně chyb, ale nezobrazí se ve Správci rozšíření.V takovém případě můžete odebrat rozšíření odstraněním souboru z následujícího umístění, kde %LocalAppData% je obvykle DriveName:\Users\UserName\AppData\Local:
%LocalAppData%\Microsoft\VisualStudio\12.0\Extensions
Příklad
Tento příklad vyhledá smyčky ve vztahu závislosti mezi prvky.
Ověří při uložení i při příkazu nabídky ověřit.
/// <summary>
/// Verify that there are no loops in the dependency relationsips.
/// In our project, no element should be a dependent of itself.
/// </summary>
/// <param name="context">Validation context for logs.</param>
/// <param name="element">Element to start validation from.</param>
[Export(typeof(System.Action<ValidationContext, object>))]
[ValidationMethod(ValidationCategories.Menu
| ValidationCategories.Save | ValidationCategories.Open)]
public void NoDependencyLoops(ValidationContext context, INamedElement element)
{
// The validation framework will call this method
// for every element in the model. But when we follow
// the dependencies from one element, we will validate others.
// So we keep a list of the elements that we don't need to validate again.
// The list is kept in the context cache so that it is passed
// from one execution of this method to another.
List<INamedElement> alreadySeen = null;
if (!context.TryGetCacheValue("No dependency loops", out alreadySeen))
{
alreadySeen = new List<INamedElement>();
context.SetCacheValue("No dependency loops", alreadySeen);
}
NoDependencyLoops(context, element,
new INamedElement[0], alreadySeen);
}
/// <summary>
/// Log an error if there is any loop in the dependency relationship.
/// </summary>
/// <param name="context">Validation context for logs.</param>
/// <param name="element">The element to be validated.</param>
/// <param name="dependants">Elements we've followed in this recursion.</param>
/// <param name="alreadySeen">Elements that have already been validated.</param>
/// <returns>true if no error was detected</returns>
private bool NoDependencyLoops(ValidationContext context,
INamedElement element, INamedElement[] dependants,
List<INamedElement> alreadySeen)
{
if (dependants.Contains(element))
{
context.LogError(string.Format("{0} should not depend on itself", element.Name),
"Fabrikam.UML.NoGenLoops", // unique code for this error
dependants.SkipWhile(e => e != element).ToArray());
// highlight elements that are in the loop
return false;
}
INamedElement[] dependantsPlusElement =
new INamedElement[dependants.Length + 1];
dependants.CopyTo(dependantsPlusElement, 0);
dependantsPlusElement[dependantsPlusElement.Length - 1] = element;
if (alreadySeen.Contains(element))
{
// We have already validated this when we started
// from another element during this validation run.
return true;
}
alreadySeen.Add(element);
foreach (INamedElement supplier in element.GetDependencySuppliers())
{
if (!NoDependencyLoops(context, supplier,
dependantsPlusElement, alreadySeen))
return false;
}
return true;
}