Sprawdzanie poprawności w języku specyficzne dla domeny
Jako autor języka specyficzne dla domeny (DSL) można zdefiniować ograniczeń sprawdzania poprawności, sprawdź, czy model, utworzone przez użytkownika jest znaczące.Na przykład jeśli modem DSL umożliwia użytkownikom rysowanie drzewa genealogicznego osób i ich przodków, można napisać ograniczenie, które gwarantuje, że daty urodzenia po ich rodziców dzieci.
Program może wykonać, gdy model jest zapisywany, gdy jest otwierany i gdy użytkownik jawnie uruchomi ograniczeń sprawdzania poprawności sprawdzania poprawności polecenia menu.Można również wykonywać sprawdzanie poprawności pod kontrolą programu.Na przykład można wykonać sprawdzania poprawności w odpowiedzi na zmianę wartości właściwości lub relacji.
Sprawdzanie poprawności jest szczególnie ważne, jeśli są zapisywane szablony tekstu lub innych narzędzi, które przetwarzają modeli użytkowników.Sprawdzanie poprawności zapewnia, że modele spełniają warunki wstępne zakłada, że za pomocą tych narzędzi.
Przestroga |
---|
Można również zezwolić ograniczeń sprawdzania poprawności określonych w oddzielnych rozszerzeń do linii DSL, wraz z rozszerzeniem poleceń menu i obsługi gestu.Użytkownicy mogą wybrać do zainstalowania tych rozszerzeń, dodatkowo do linii DSL.Aby uzyskać więcej informacji, zobacz Przedłużenie linii DSL za pomocą MEF. |
Podczas edycji modelu, oznacza to wystąpienie język specyficzne dla domeny, następujące działania można uruchomić sprawdzania poprawności:
Kliknij diagram prawym przyciskiem myszy i wybierz Sprawdź poprawność wszystkich.
Kliknij prawym przyciskiem myszy węzeł najwyższego poziomu w Eksploratorze DSL i wybierz Sprawdź poprawność wszystkich
Zapisz model.
Otwórz model.
Ponadto można napisać kod programu, który uruchamia sprawdzanie poprawności, na przykład, jako część polecenia menu lub w odpowiedzi na zmiany.
Wszelkie błędy sprawdzania poprawności pojawią się w Listy błędów okna.Użytkownika można kliknąć dwukrotnie komunikat o błędzie, aby wybrać elementy modelu, które są przyczyną błędu.
Sprawdzanie poprawności ograniczenia należy zdefiniować przez dodanie metody sprawdzania poprawności do domeny klas lub relacji linii DSL.Podczas sprawdzania poprawności jest uruchamiany przez użytkownika lub pod kontrolą programu, niektóre lub wszystkie metody sprawdzania poprawności są wykonywane.Każda metoda jest stosowana do każdego wystąpienia danej klasy, a każda klasa może być kilka metod sprawdzania poprawności.
Każda metoda sprawdzania poprawności raportuje wszystkie błędy, które znajdzie.
[!UWAGA]
Metody sprawdzania poprawności raportowanie błędów, ale nie zmienianie modelu.Jeśli chcesz dostosować lub zapobiegania niektórych zmian, zobacz rozwiązania alternatywne do sprawdzania poprawności.
Włączanie sprawdzania poprawności w Editor\Validation węzła:
Open Dsl\DslDefinition.dsl.
W Eksploratorze DSL, rozwiń węzeł edytora węzeł i wybierz sprawdzania poprawności.
W oknie dialogowym właściwości ustaw korzysta z właściwości, aby true.Jest najbardziej odpowiednim czasie ustawić te właściwości.
Kliknij przycisk Transform wszystkie szablony na pasku narzędziowym panelu Solution Explorer.
Napisz definicji częściowej klasy dla jednego lub więcej klas domeny lub domeny w relacji.Zapisać te definicje w nowym pliku kodu w Dsl projektu.
Prefiks każdej klasy z tego atrybutu:
[ValidationState(ValidationState.Enabled)]
- Domyślnie ten atrybut również włączyć sprawdzanie poprawności dla klas pochodnych.Aby wyłączyć sprawdzanie poprawności dla określonej klasy pochodnej, można użyć ValidationState.Disabled.
Metody sprawdzania poprawności należy dodać do klasy.Każda metoda sprawdzania poprawności może mieć dowolną nazwę, ale mieć jeden parametr typu ValidationContext.
Musi być opatrzony prefiksem z jednym lub więcej ValidationMethod atrybuty:
[ValidationMethod (ValidationCategories.Open | ValidationCategories.Save | ValidationCategories.Menu ) ]
ValidationCategories Określa, kiedy metoda jest wykonywany.
Na przykład:
using Microsoft.VisualStudio.Modeling;
using Microsoft.VisualStudio.Modeling.Validation;
// Allow validation methods in this class:
[ValidationState(ValidationState.Enabled)]
// In this DSL, ParentsHaveChildren is a domain relationship
// from Person to Person:
public partial class ParentsHaveChildren
{
// Identify the method as a validation method:
[ValidationMethod
( // Specify which events cause the method to be invoked:
ValidationCategories.Open // On file load.
| ValidationCategories.Save // On save to file.
| ValidationCategories.Menu // On user menu command.
)]
// This method is applied to each instance of the
// type (and its subtypes) in a model:
private void ValidateParentBirth(ValidationContext context)
{
// In this DSL, the role names of this relationship
// are "Child" and "Parent":
if (this.Child.BirthYear < this.Parent.BirthYear
// Allow user to leave the year unset:
&& this.Child.BirthYear != 0)
{
context.LogError(
// Description:
"Child must be born after Parent",
// Unique code for this error:
"FAB001ParentBirthError",
// Objects to select when user double-clicks error:
this.Child,
this.Parent);
}
}
Zawiadomienie o tym kodzie następujące punkty:
Metody sprawdzania poprawności można dodać do domeny klas lub relacji domen.Kod dla tych typów znajduje się w Dsl\Generated Code\Domain*.cs.
Każda metoda sprawdzania poprawności jest stosowany do każdego wystąpienia danej klasy i jej podklas.W przypadku relacji domen, każde wystąpienie jest łącze między dwoma elementami modelu.
Metody sprawdzania poprawności nie są stosowane w określonej kolejności i każda metoda nie jest stosowana dla wystąpienia klasy, jej w dowolnej kolejności przewidywalne.
Dzieje się tak zazwyczaj bad praktyki dla metody sprawdzania poprawności zaktualizować zawartość magazynu prowadziłoby to do niespójnych wyników.Zamiast tego raportu jakikolwiek błąd, wywołując metodę context.LogError, LogWarning lub LogInfo.
W wywołaniu LogError może dostarczyć listę elementów modelu lub łączami relacji zostanie zaznaczone, gdy użytkownik kliknie dwukrotnie komunikat o błędzie.
Aby uzyskać informacje dotyczące odczytywania modelu w kod programu, zobacz Przeglądanie i aktualizowanie modelu w kod programu.
Przykład stosuje się do następujących modelu domeny.Relacja ParentsHaveChildren ma ról, które noszą podrzędnej i nadrzędnej.
W ValidationMethod atrybut, można określić podczas powinien być wykonywany metody sprawdzania poprawności.
Kategoria |
Wykonanie |
---|---|
Gdy użytkownik wywołuje polecenie Sprawdź poprawność. |
|
Przy otwieraniu pliku modelu. |
|
Gdy plik jest zapisywany.Jeśli istnieją błędy sprawdzania poprawności, użytkownik będzie miał opcji Zapisz anulowanie operacji. |
|
Gdy plik jest zapisywany.Jeśli wystąpią błędy, które z metod opisanych w tej kategorii, użytkownik jest ostrzegany, że może nie być możliwe ponowne otwarcie pliku. Użyj tej kategorii dla metod sprawdzania poprawności, które testują dla zduplikowanych nazw lub identyfikatorów lub inne warunki, które mogą powodować błędy ładowania. |
|
Gdy wywoływana jest metoda ValidateCustom.Sprawdzanie poprawności w tej kategorii mogą być wywoływane tylko z kodu programu. Aby uzyskać więcej informacji, zobacz Niestandardowe sprawdzania poprawności kategorii. |
Ten sam efekt można osiągnąć często przez wprowadzenie metody sprawdzania poprawności na innego typu.Na przykład można dodać metodę klasy osoba w relacji ParentsHaveChildren i go iterację łącza:
[ValidationState(ValidationState.Enabled)]
public partial class Person
{[ValidationMethod
( ValidationCategories.Open
| ValidationCategories.Save
| ValidationCategories.Menu
)
]
private void ValidateParentBirth(ValidationContext context)
{
// Iterate through ParentHasChildren links:
foreach (Person parent in this.Parents)
{
if (this.BirthYear <= parent.BirthYear)
{ ...
Zsumowanie ograniczeń sprawdzania poprawności. Zastosowanie sprawdzania poprawności w ustalonym porządku, zdefiniować metodę sprawdzania poprawności pojedynczej klasy właściciela takiego elementu głównego modelu.Ta technika umożliwia również skumulować wiele raportów o błędach w pojedynczej wiadomości.
Wady są że połączone metoda jest mniej łatwe w zarządzaniu i że ograniczenia muszą wszystkie mają taki sam ValidationCategories.Dlatego zaleca się zachować każde ograniczenie w oddzielnych metody, jeśli jest to możliwe.
Przekazywanie wartości w pamięci podręcznej kontekstu. Parametr kontekstu ma słownik, w którym można umieścić dowolne wartości.Słownik będzie się powtarzał dla życia uruchomienia sprawdzania poprawności.Metoda sprawdzania poprawności w szczególności może, na przykład, przechowuje licznika błędów w kontekście i umożliwia unikanie zalewania okno błąd z powtarzających się wiadomości.Na przykład:
List<ParentsHaveChildren> erroneousLinks;
if (!context.TryGetCacheValue("erroneousLinks", out erroneousLinks))
erroneousLinks = new List<ParentsHaveChildren>();
erroneousLinks.Add(this);
context.SetCacheValue("erroneousLinks", erroneousLinks);
if (erroneousLinks.Count < 5) { context.LogError( ... ); }
Metody sprawdzania poprawności dla sprawdzania minimalna liczebności są generowane automatycznie dla linii DSL.Kod jest zapisywany do Dsl\Generated Code\MultiplicityValidation.cs.Metody te zostały wprowadzone po włączeniu sprawdzania poprawności w Editor\Validation węzeł w Eksploratorze DSL.
Jeśli ustawisz liczebność roli w relacji domeny 1.. * lub 1..1, ale użytkownik nie tworzy łącze tej relacji, zostanie wyświetlony komunikat o błędzie sprawdzania poprawności.
Na przykład, jeśli modem DSL ma klasy osoby i Miasto i relacji PersonLivesInTown z relacją 1.. * w roli Miasto następnie dla każdej osobie, której nie Miasto ma komunikat o błędzie pojawi się.
Można uruchomić sprawdzanie poprawności dostępu lub tworząc ValidationController.Błędy, które mają być wyświetlane użytkownikowi w oknie błędów, należy użyć ValidationController, dołączonego do DocData dla diagramu.Na przykład, jeśli piszesz polecenia menu CurrentDocData.ValidationController jest dostępna w klasie zestaw poleceń:
using Microsoft.VisualStudio.Modeling;
using Microsoft.VisualStudio.Modeling.Validation;
using Microsoft.VisualStudio.Modeling.Shell;
...
partial class MyLanguageCommandSet
{
private void OnMenuMyContextMenuCommand(object sender, EventArgs e)
{
ValidationController controller = this.CurrentDocData.ValidationController;
...
Aby uzyskać więcej informacji, zobacz Jak: Dodawanie polecenia do Menu skrótów.
Można również utworzyć kontroler oddzielnych sprawdzania poprawności i samodzielnie zarządzać błędy.Na przykład:
using Microsoft.VisualStudio.Modeling;
using Microsoft.VisualStudio.Modeling.Validation;
using Microsoft.VisualStudio.Modeling.Shell;
...
Store store = ...;
VsValidationController validator = new VsValidationController(s);
// Validate all elements in the Store:
if (!validator.Validate(store, ValidationCategories.Save))
{
// Deal with errors:
foreach (ValidationMessage message in validator.ValidationMessages) { ... }
}
Jeśli chcesz upewnić się, że użytkownik jest niezwłocznie powiadamiany Jeśli model staje się nieprawidłowy, można zdefiniować zdarzenia magazynu, który uruchamia sprawdzanie poprawności.Aby uzyskać więcej informacji na temat zdarzenia magazynu, zobacz Programy obsługi zdarzeń propagowanie zmian poza modelu.
Oprócz kodu sprawdzania poprawności Dodawanie pliku niestandardowego kodu do sieci DslPackage projektu z zawartością podobny do następującego przykładu.Ten kod zawiera ValidationController dołączony do dokumentu.Ten kontroler wyświetla błędy sprawdzania poprawności w Visual Studio lista błędów.
using System;
using System.Linq;
using Microsoft.VisualStudio.Modeling;
using Microsoft.VisualStudio.Modeling.Validation;
namespace Company.FamilyTree
{
partial class FamilyTreeDocData // Change name to your DocData.
{
// Register the store event handler:
protected override void OnDocumentLoaded()
{
base.OnDocumentLoaded();
DomainClassInfo observedLinkInfo = this.Store.DomainDataDirectory
.FindDomainClass(typeof(ParentsHaveChildren));
DomainClassInfo observedClassInfo = this.Store.DomainDataDirectory
.FindDomainClass(typeof(Person));
EventManagerDirectory events = this.Store.EventManagerDirectory;
events.ElementAdded
.Add(observedLinkInfo, new EventHandler<ElementAddedEventArgs>(ParentLinkAddedHandler));
events.ElementDeleted.Add(observedLinkInfo, new EventHandler<ElementDeletedEventArgs>(ParentLinkDeletedHandler));
events.ElementPropertyChanged.Add(observedClassInfo, new EventHandler<ElementPropertyChangedEventArgs>(BirthDateChangedHandler));
}
// Handler will be called after transaction that creates a link:
private void ParentLinkAddedHandler(object sender,
ElementAddedEventArgs e)
{
this.ValidationController.Validate(e.ModelElement,
ValidationCategories.Save);
}
// Called when a link is deleted:
private void ParentLinkDeletedHandler(object sender,
ElementDeletedEventArgs e)
{
// Don't apply validation to a deleted item!
// - Validate store to refresh the error list.
this.ValidationController.Validate(this.Store,
ValidationCategories.Save);
}
// Called when any property of a Person element changes:
private void BirthDateChangedHandler(object sender,
ElementPropertyChangedEventArgs e)
{
Person person = e.ModelElement as Person;
// Not interested in changes in other properties:
if (e.DomainProperty.Id != Person.BirthYearDomainPropertyId)
return;
// Validate all parent links to and from the person:
this.ValidationController.Validate(
ParentsHaveChildren.GetLinksToParents(person)
.Concat(ParentsHaveChildren.GetLinksToChildren(person))
, ValidationCategories.Save);
}
}
}
Programy obsługi są również nazywane po operacji Cofnij i ponów, które wpływają na łącza lub elementy.
Oprócz kategorie standardowych sprawdzania poprawności, takich jak Menu i otwórz można zdefiniować własne kategorie.Można wywoływać te kategorie z kodu programu.Użytkownik nie może wywołać je bezpośrednio.
Typowym zastosowaniem niestandardowych kategorii jest określenie kategorii, który sprawdza, czy wzór spełnia warunki specyficzne narzędzie.
Metoda sprawdzania poprawności należy dodać do określonej kategorii, go prefiksem atrybut następująco:
[ValidationMethod(CustomCategory = "PreconditionsForGeneratePartsList")]
[ValidationMethod(ValidationCategory.Menu)]
private void TestForCircularLinks(ValidationContext context)
{...}
[!UWAGA]
Można prefiks metody z tylu [ValidationMethod()] atrybuty, jak chcesz.Metodę można dodać do kategorii standardowymi i niestandardowymi.
Aby wywołać niestandardowy sprawdzania poprawności:
// Invoke all validation methods in a custom category:
validationController.ValidateCustom
(store, // or a list of model elements
"PreconditionsForGeneratePartsList");
Sprawdzanie poprawności ograniczeń raportowanie błędów, ale nie zmienić model.Jeśli natomiast chcesz zapobiec modelu, staje się nieprawidłowy, można użyć innych technik.
Techniki te nie są jednak zalecane.Jest ona zazwyczaj lepiej umożliwić użytkownikowi zdecydować, jak poprawić nieprawidłowy model.
Dopasowywanie zmiany, aby przywrócić modelu ważności. Na przykład jeśli użytkownik ustawi właściwość powyżej dozwolone maksimum, można zresetować właściwość na wartość maksymalną.Aby to zrobić, należy zdefiniować regułę.Aby uzyskać więcej informacji, zobacz Zasady propagowanie zmian w ramach modelu.
Wycofywanie transakcji, jeżeli próba jest nieprawidłowa zmiana. Można również zdefiniować regułę, w tym celu, ale w niektórych przypadkach można zastąpić obsługi właściwości jest OnValueChanging(), lub aby zastąpić metody, takie jak OnDeleted(). , aby wycofać transakcji, należy użyć this.Store.TransactionManager.CurrentTransaction.Rollback(). uzyskać więcej informacji, zobacz Domen właściwość wartość zmiany obsługi.
Przestroga |
---|
Upewnij się, że użytkownik wie, że zmiany zostały dostosowane lub wycofana.Na przykład użyćSystem.Windows.Forms.MessageBox.Show("message"). |