Udostępnij za pośrednictwem


Porady: definiowanie ograniczeń walidacji dla modeli UML

W Visual Studio Ultimate, można określić ograniczenia sprawdzania poprawności, które sprawdzają, czy model spełnia określony warunek.Na przykład można zdefiniować ograniczenie, aby upewnić się, że użytkownik nie utworzy pętli relacji dziedziczenia.Ograniczenie jest wywoływane, gdy użytkownik próbuje otworzyć lub zapisać model i można także uruchomić ręcznie.Jeśli ograniczenie nie powiedzie się, komunikat o błędzie, który zdefiniujesz jest dodawany do okna błędu.Można spakować te ograniczenia w Visual Studio Rozszerzeniu integracji (VSIX) i przesyłać je do innych Visual Studio Ultimate użytkowników.

Można również zdefiniować ograniczenia, które sprawdzają poprawność modelu przed zasobami zewnętrznymi, takimi jak bazy danych.

[!UWAGA]

Jeśli chcesz sprawdzić poprawność kodu programu względem diagramu warstwy, zobacz Dodawanie walidacji niestandardowej architektury do diagramów warstw.

Wymagania

Stosowanie ograniczeń sprawdzania poprawności

Sprawdzanie poprawności ograniczenia jest stosowane w trzech przypadkach: po zapisaniu modelu; po otwarciu modelu; i po kliknięciu Sprawdź poprawność modelu UML w menu Architektury.W każdym przypadku, tylko ograniczenia, które zostały zdefiniowane dla tego przypadku zostaną zastosowane, chociaż zazwyczaj można zdefiniować każde ograniczenie do zastosowania w więcej niż jednym przypadku.

Błędy sprawdzania poprawności są zgłaszane w Visual Studio oknie błędów, a następnie można kliknąć dwukrotnie błąd, aby wybrać elementy modelu, które znajdują się w błędzie.

Aby uzyskać więcej informacji dotyczących stosowania walidacji, zobacz Walidacja modelu UML.

Definiowanie rozszerzenia sprawdzania poprawności

Aby utworzyć rozszerzenie sprawdzania poprawności dla projektanta UML, należy utworzyć klasę, która definiuje ograniczenia sprawdzania poprawności i osadzić tę klasę w rozszerzeniu Visual Studio Integration (VSIX)VSIX działa jako kontener, który może zainstalować ograniczenie.Istnieją dwie alternatywne metody definiowania rozszerzenia sprawdzania poprawności:

  • Utwórz rozszerzenie walidacji w jego własnym VSIX przy użyciu szablonu projektu. To jest szybsza metoda.Użyj go, jeśli nie chcesz połączyć ograniczeń sprawdzania poprawności z innymi rodzajami rozszerzeń takich jak polecenia menu, elementy do przybornika niestandardowego lub program obsługi gestów.Można zdefiniować kilka ograniczeń w jednej klasie.

  • Utwórz osobną klasę weryfikacji i projektów VSIX. Metoda ta jest używana, jeśli chcesz połączyć kilka rodzajów rozszerzeń w samym VSIX.Na przykład, jeśli polecenie menu oczekuje modelu do przestrzegania szczególnych ograniczeń, można go osadzić w samym VSIX jako metodę sprawdzania poprawności.

Aby utworzyć rozszerzenie sprawdzania poprawności w jego własnym VSIX

  1. W oknie dialogowym Nowy projekt w polu Projekty modelowania, wybierz opcję Rozszerzenie sprawdzania poprawności.

  2. Otwórz .cs plik w nowym projekcie i modyfikuj klasę, aby wdrożyć swoje ograniczenia sprawdzania poprawności.

    Aby uzyskać więcej informacji, zobacz Implementacja ograniczenia walidacji.

    Ważna uwagaWażne

    Upewnij się, że Twój pliki .cs zawiera następujące instrukcje using:

    using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Uml;

  3. Możesz dodać dodatkowe ograniczenia definiując nowe metody.Aby określić metodę jako metodę sprawdzania poprawności, musi być ona oznakowana atrybutami w taki sam sposób, jak metoda wstępnego sprawdzania poprawności.

  4. Przetestuj swoje ograniczenia, naciskając klawisz F5.Aby uzyskać więcej informacji, zobacz Uruchamianie walidacji.

  5. Zainstaluj polecenie menu na innym komputerze przez skopiowanie pliku bin\*\*.vsix utworzonego w projekcie.Aby uzyskać więcej informacji, zobacz Instalowanie ograniczeń walidacji.

Po dodaniu innych .cs plików, będzie zwykle wymagają następującej using instrukcji:

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;

W tym miejscu jest alternatywna procedura:

Aby utworzyć ograniczenie osobnego sprawdzania poprawności w projekcie klasy biblioteki

  1. Utwórz projekt biblioteki klas, dodając go do istniejącego rozwiązania VSIX albo tworząc nowe rozwiązanie.

    1. W pasku menu wybierz Plik, Nowy, Projekt.

    2. Pod zainstalowane szablony, rozwiń programu Visual C# lub język Visual Basic, a następnie w środkowej kolumnie Wybierz Biblioteka klas.

  2. Chyba że rozwiązanie zawiera już jeden, utwórz projekt VSIX:

    1. W Eksploratorze rozwiązań w menu skrótów rozwiązania wybierz Dodaj, Nowy projekt.

    2. Pod zainstalowane szablony, rozwiń program Visual C# lub program Visual Basic, następnie wybierz rozszerzalności.W środkowej kolumnie kliknij Projekt VSIX.

  3. Ustaw projekt VSIX jako projekt startowy rozwiązania.

    • W Eksploratorze rozwiązań, w menu skrótów projektu VSIX wybierz Ustaw jako projekt startowy.
  4. W source.extension.vsixmanifest w polu Zawartość dodaj projekt biblioteki klas jako składnik MEF:

    1. W zakładce Metadane ustaw nazwę VSIX.

    2. W zakładce Instaluj obiekty docelowe ustaw program Visual Studio Ultimate i Premium jako obiekty docelowe.

    3. W zakładce Aktywa wybierz polecenie Nowy i w oknie dialogowym ustaw:

      Typ = składnik MEF

      Źródło = projektu w bieżącym rozwiązaniu

      Projekt = Your class library project

Aby zdefiniować klasę walidacji

  1. Ta procedura jest zbędna, jeśli utworzono klasy weryfikacji z własnej VSIX z szablonu projektu sprawdzania poprawności.

  2. W projekcie klasy sprawdzania poprawności dodaj odwołania do następujących zestawów .NET:

    Microsoft.VisualStudio.Modeling.Sdk.12.0

    Microsoft.VisualStudio.ArchitectureTools.Extensibility.Uml

    Microsoft.VisualStudio.Uml.Interfaces

    System.ComponentModel.Composition

  3. Dodaj plik do projektu biblioteki klas zawierający kod, który jest podobny do następującego przykładu.

    • Każde ograniczenie sprawdzania poprawności jest zawarte w metodzie, która jest oznaczona szczególnym atrybutem.Metoda akceptuje parametr typu elementu modelu.Podczas wywołania sprawdzania poprawności, szablon sprawdzania poprawności będzie stosował metodę sprawdzania poprawności do każdego elementu modelu, który odpowiada jego typowi parametru.

    • Metody te można umieścić w jakiejkolwiek klasie i przestrzeni nazw.Zmień je na swoje preferencje.

    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.
      }
    }
    

Wykonywanie ograniczenia sprawdzania poprawności

Do celów testowych wykonaj metody walidacji w trybie debugowania.

Aby przetestować ograniczenie sprawdzania poprawności

  1. Naciśnij klawisz F5 lub w menu Debugowanie zaznacz Rozpocznij debugowanie.

    Eksperymentalne wystąpienie Visual Studio rozpoczyna się.

    Rozwiązywanie problemów z: Jeśli nowego Visual Studio nie można uruchomić:

    • Jeśli masz więcej niż jeden projekt, upewnij się, że projekt VSIX jest ustawiony jako projekt startowy rozwiązania.

    • W Eksploratorze rozwiązań, w menu skrótów uruchamiania lub tylko projektu, wybierz Właściwości.W edytorze właściwości projektu zaznacz kartę Debugowanie.Upewnij się, że ciąg w polu Uruchomienie zewnętrznego programu jest pełną nazwą ścieżki Visual Studio, zazwyczaj:

      C:\Program Files\Microsoft Visual Studio 12.0\Common7\IDE\devenv.exe

  2. W eksperymentalnym Visual Studio, otwórz lub stwórz projektu modelowania i otworzyć lub utworzyć diagram modelowania.

  3. Aby skonfigurować test próbki ograniczenia podany w poprzedniej sekcji:

    1. Otwórz diagram klas

    2. Utwórz klasę i dodaj dwa atrybuty, które mają taką samą nazwę.

  4. W menu skrótów w dowolnym miejscu na diagramie wybierz Sprawdzanie poprawności.

  5. Wszelkie błędy w modelu będą raportowane w oknie błędów.

  6. Kliknij dwukrotnie raport o błędzie.Jeśli elementy wymienione w raporcie są widoczne na ekranie, zostaną one wyróżnione.

    Rozwiązywanie problemów z: Jeśli Sprawdzanie poprawności w menu nie ma polecenia, upewnij się, że:

    • Projekt sprawdzania poprawności jest wymieniony jako składnik listy MEF zakładki Aktywa w source.extensions.manifest w projekcie VSIX.

    • Poprawne Export i ValidationMethod atrybuty są dołączone do metody sprawdzania poprawności.

    • ValidationCategories.Menu zawarte w argumencie ValidationMethod atrybutu i składa się z innych wartości przy użyciu logicznych lub (|).

    • Parametry wszystkich Import i Export atrybuty są prawidłowe.

Ocena ograniczenia

Metoda sprawdzania poprawności powinna ustalić, czy ograniczenie sprawdzania poprawności, które chcesz zastosować jest wartość PRAWDA lub FAŁSZ.Jeśli ma wartość true, to nie należy nic robić.W przypadku wartości fałsz, należy zgłosić błąd przy użyciu metod dostarczonych przez parametr ValidationContext.

[!UWAGA]

Metody sprawdzania poprawności nie powinny zmieniać modelu.Nie istnieją żadne gwarancje, kiedy i w jakiej kolejności ograniczenia zostaną wykonane.Jeśli musisz przekazać informacje między kolejnymi wykonaniami metody sprawdzania poprawności w ramach przebiegu weryfikacji, można użyć pamięci podręcznej kontekstu opisanej w części Koordynacja wielokrotnego sprawdzania poprawności.

Na przykład, jeśli chcesz zapewnić, że każdy typ (klasa, interfejs lub moduł wyliczający) ma nazwę, która składa się z co najmniej trzech znaków, można użyć tej metody:

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);
   }
 }

Zobacz Programowanie za pomocą API UML, aby uzyskać informacje o metodach i typach, których możesz użyć do nawigacji i odczytania modelu.

Sprawdzanie poprawności ograniczenia metody — informacje

Każde ograniczenie sprawdzania poprawności jest określone metodą następującej postaci:

[Export(typeof(System.Action<ValidationContext, object>))]
 [ValidationMethod(ValidationCategories.Save 
  | ValidationCategories.Menu 
  | ValidationCategories.Open)]
public void ValidateSomething
  (ValidationContext context, IClassifier elementToValidate)
{...}

Atrybuty i parametry każdej metody sprawdzania poprawności są następujące:

[Export(typeof(System.Action <ValidationContext, object>))]

Definiuje metodę jako ograniczenie walidacji za pomocą Managed Extensibility Framework (MEF).

[ValidationMethod (ValidationCategories.Menu)]

Określa, kiedy będzie można wykonać sprawdzania poprawności.Użyj wartości logicznej lub (|), jeśli chcesz połączyć więcej niż jedną opcję.

Menu = wywoływany przez menu sprawdzania poprawności.

Save = wywoływana przy zapisywaniu modelu.

Open = wywoływana na otwieranie modelu.Load = wywoływana przy zapisywaniu modelu, ale z powodu naruszenia ostrzega użytkownika że może nie być możliwe, aby ponownie otworzyć model.Wywoływany także w czasie ładowania, zanim model jest analizowany.

public void ValidateSomething

(ValidationContext context,

IElement element)

Zamień drugi parametr IElement przez typ elementu, do którego chcesz zastosować ograniczenie.Metoda ograniczenia zostanie wywołana na wszystkie elementy określonego typu.

Nazwa metody jest nieważna.

Można zdefiniować taką liczbę metod sprawdzania poprawności, jaką chcesz, z różnymi typami w drugim parametrze.Podczas wywoływania sprawdzania poprawności, każda metoda każda metoda sprawdzania poprawności będzie wywoływana dla każdego elementu modelu, który jest zgodny z typem parametru.

Raportowanie błędów sprawdzania poprawności

Aby utworzyć raport o błędach, należy użyć metod dostarczonych przez ValidationContext:

context.LogError("error string", errorCode, elementsWithError);

  • "error string" pojawia się na Liście błędów Visual Studio

  • errorCode jest ciągiem, który powinien być unikatowym identyfikatorem błędu

  • elementsWithError identyfikuje elementy w modelu.Gdy użytkownik kliknie dwukrotnie raport o błędach, zostanie wybrany kształt reprezentujący ten element.

LogError(),LogWarning() i LogMessage() umieszczają wiadomości w różnych sekcjach listy błędów.

W jaki sposób są stosowane metody sprawdzania poprawności

Sprawdzania poprawności jest stosowane do każdego elementu w modelu, w tym relacji i części większych elementy, takich jak atrybuty klasy i parametry operacji.

Każda metoda sprawdzania poprawności jest stosowana do każdego elementu, który jest zgodny z typem określonym w swoim drugim parametrze.Oznacza to, że na przykład po zdefiniowaniu metody sprawdzania poprawności z drugim parametrem IUseCase , a drugi z jego nadtypów IElement, a następnie obie te metody będą stosowane do każdego przypadku użycia w modelu.

Hierarchia typów jest podsumowywana w Typy elementów modelu.

Możesz także uzyskać dostęp do elementów poprzez następujące relacje.Na przykład, jeśli istnieje potrzeba zdefiniowania metody sprawdzania poprawności IClass, można przejść przez jej własne właściwości:

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);
        }
   }
}

Tworzenie metody sprawdzania poprawności na modelu

Jeśli chcesz mieć pewność, że metoda sprawdzania poprawności jest wywoływana tylko raz podczas każdego przebiegu walidacji, można sprawdzić poprawność 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)
   { ...

Sprawdzanie poprawności kształtów i diagramów

Metody sprawdzania poprawności nie są wywoływane na wyświetlanych elementach, takich jak diagramy i kształty, ponieważ podstawowym celem metody sprawdzania poprawności jest sprawdzania poprawności modelu.Ale możesz uzyskać dostęp do bieżącego diagramu korzystając z kontekstu diagramu.

W klasie sprawdzania poprawności zadeklaruj DiagramContext jako właściwość importowaną:

using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Presentation; 
...
[Import]
public IDiagramContext DiagramContext { get; set; }

W metodzie sprawdzania poprawności, można korzystać z DiagramContext, aby uzyskać dostęp do bieżącego diagramu fokus, jeśli istnieje jeden:

[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>())
    { ...

Aby zarejestrować błąd, musisz uzyskać element modelu, który reprezentuje kształt, ponieważ nie można przekazać kształtu do LogError:

       IUseCase useCase = useCaseShape.Element;
       context.LogError(... , usecase);

Koordynowanie wielokrotnego sprawdzania poprawności

Podczas sprawdzania poprawności, na przykład przez użytkownika menu wykresu, każda metoda sprawdzania poprawności ma zastosowanie do każdego elementu modelu.Oznacza to, że w pojedynczej grupy wywołanie RAM sprawdzania poprawności. tę samą metodę można stosować wiele razy do różnych elementów.

To stanowi problem dla sprawdzanie poprawności, które zajmuje się relacją między elementami.Na przykład można wpisać sprawdzanie poprawności, które zaczyna się, powiedzmy, od przypadku użycia i sprawdzić relacje include, aby zweryfikować, że nie istnieją żadne pętle.Ale kiedy metoda jest stosowana do każdego przypadku użycia w modelu z wieloma łączami include, prawdopodobnie będzie wielokrotnie przetwarzać te same obszary modelu.

Aby uniknąć tej sytuacji, istnieje pamięć podręczna kontekstu, w której jest przechowywana informacja podczas uruchomienia sprawdzania poprawności.Można go używać do przekazywania informacji między różnymi wykonaniami metody sprawdzania poprawności.Można na przykład przechowywać listę elementów, które już zostały uwzględnione w tym przebiegu weryfikacji.Pamięć podręczna jest tworzona na początku każdego przebiegu weryfikacji i nie może służyć do przekazywania informacji między różne procesy sprawdzania poprawności.

context.SetCacheValue<T> (name, value)

Wartość magazynu

context.TryGetCacheValue<T> (name, out value)

Pobierz wartość.Zwraca true, jeśli kończy się pomyślnie.

context.GetValue<T>(name)

Pobierz wartość.

Context.GetValue<T>()

Pobierz wartość określonego typu.

Instalowanie i odinstalowywanie rozszerzenia

Można zainstalować Visual Studio rozszerzenie zarówno na swoim komputerze jak i na innych komputerach.

Aby zainstalować rozszerzenie

  1. Na komputerze, należy odnaleźć .vsix plik, który został zbudowany w danym projekcie VSIX.

    1. W Eksploratorze rozwiązań, w menu skrótów projektu VSIX wybierz Otwórz folder w Eksploratorze Windows.

    2. Zlokalizuj plik bin\*\YourProject.vsix

  2. Kopiuj plik .vsix do komputera miejsca docelowego, na którym chcesz zainstalować rozszerzenie.Może to być twój własny komputer, albo inny.

    • Komputer docelowy musi mieć jedną z wersji systemu Visual Studio określonej w source.extension.vsixmanifest.
  3. Na komputerze docelowym otwórz .vsix pliku.

    Instalator rozszerzenia programu Visual Studio otwiera i instaluje rozszerzenia.

  4. Uruchom lub ponownie uruchom Visual Studio.

Aby odinstalować rozszerzenie

  1. W menu Narzędzia wybierz Menedżer rozszerzeń.

  2. Rozwiń Zainstalowane rozszerzenia.

  3. Zaznacz rozszerzenie, a następnie wybierz Odinstaluj.

Rzadko wadliwe rozszerzenie nie ładuje się i tworzy raport w oknie błędów, ale nie pojawia się w Menedżerze rozszerzeń.W takim przypadku można usunąć rozszerzenie poprzez usunięcie pliku z następującej lokalizacji, gdzie %LocalAppData% jest zazwyczaj DriveName: \Users\UserName\AppData\Local:

%LocalAppData%\Microsoft\VisualStudio\12.0\Extensions

Przykład

W tym przykładzie wyszukuje pętli w relacji zależności między elementami.

Będzie sprawdzać poprawność na poleceniu menu zapisu i sprawdzania poprawności.

/// <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;
}

Zobacz też

Koncepcje

Porady: definiowanie i instalowanie rozszerzenia modelowania

Programowanie za pomocą API UML