도메인별 언어에서 유효성 검사

도메인 관련 언어 (DSL)의 작성자는 사용자가 만든 모델 의미 있는 확인 합니다 유효성 검사 제약 조건을 정의할 수 있습니다.예를 들어,를 DSL 사용자 및 해당 상위의 패밀리 트리를 그릴 수 있습니다 되 면 생년월일 후 부모 자식을 가질 수 제한을 쓸 수 있습니다.

열 때 모델에 저장 하 고 사용자가 명시적으로 실행 될 때 실행할 유효성 검사 제약 조건이 있을 수 있습니다의 유효성 검사 메뉴 명령입니다.프로그램 컨트롤에서 유효성 검사를 실행할 수도 있습니다.예를 들어, 속성 값 또는 관계 변경에 대 한 응답 유효성 검사를 실행할 수 있습니다.

유효성 검사 텍스트 서식 파일 또는 사용자의 모델을 처리 하는 도구를 작성 하는 경우에 특히 중요 합니다.유효성 검사 모델은 이러한 도구로 간주 하는 전제 조건이 충족 하 게 됩니다.

주의 정보주의

유효성 검사 제약 조건에 별도 확장 확장 메뉴 명령 및 제스처 처리기를 DSL 정의할 수 있도록 할 수도 있습니다.사용자는 DSL 이외에 이러한 확장을 설치 하려면 선택할 수 있습니다.자세한 내용은 MEF를 사용하여 DSL 확장를 참조하십시오.

유효성 검사를 실행합니다.

즉, 사용자가 모델을 편집 하는 경우 인스턴스를 도메인 관련 언어를 다음 작업 유효성 검사를 실행할 수 있습니다.

  • 다이어그램을 마우스 오른쪽 단추로 클릭 하 고 선택 의 유효성을 검사 하 고 모든.

  • DSL 및 선택의 탐색기에서 맨 위 노드를 마우스 오른쪽 단추로 모든 유효성 검사

  • 모델을 저장 합니다.

  • 모델을 엽니다.

  • 또한 유효성 검사, 예를 들어, 메뉴 명령 또는 변경에 대 한 응답에서으로 실행 프로그램 코드를 작성할 수 있습니다.

유효성 검사 오류가 표시 됩니다의 오류 목록 창입니다.사용자가 두 번 오류 메시지가 오류 원인이 되는 모델 요소를 선택 합니다.

유효성 검사 제약 조건 정의

도메인 클래스 또는 관계를 DSL에 유효성 검사 메서드를 추가 하 여 유효성 검사 제약 조건을 정의 합니다.유효성 검사는 사용자가 또는 프로그램 제어 실행 될 때 일부 또는 모든 유효성 검사 메서드가 실행 됩니다.각 방법 각 클래스의 인스턴스에 적용 됩니다 및 각 클래스에 여러 개의 유효성 검사 메서드 수입니다.

각 유효성 검사 메서드는 발견 된 오류를 보고 합니다.

[!참고]

유효성 검사 메서드는 오류를 보고 하지만 모델은 변경 되지 않습니다.필요한 경우 조정할 또는 특정 변경 금지를 참조 하십시오 대체 유효성 검사 방법.

유효성 검사 제약 조건을 정의 하려면

  1. 유효성 검사의 활성화는 Editor\Validation 노드:

    1. Dsl\DslDefinition.dsl를 엽니다.

    2. DSL 탐색기 확장은 편집기 노드 및 선택 유효성 검사.

    3. 속성 창에서 설정에서 을 사용 하 여 속성을 true.대부분의 이러한 속성을 모두 설정 하는 것이 더 편리 합니다.

    4. 클릭 모든 템플릿 변환 솔루션 탐색기 도구 모음에 있습니다.

  2. 하나 이상의 도메인 클래스 또는 도메인 관계에 대 한 partial 클래스 정의 작성 합니다.이러한 정의 새 코드 파일에 작성 하는 있는 Dsl 프로젝트입니다.

  3. 각 클래스에이 특성을 접두사:

    [ValidationState(ValidationState.Enabled)]
    
    • 기본적으로이 특성은 또한 파생된 클래스에 대 한 유효성 검사를 수 있습니다.특정 파생된 클래스에 대 한 유효성 검사를 사용 하지 않을 경우 사용할 수 있습니다 ValidationState.Disabled.
  4. 유효성 검사 메서드를 클래스에 추가 합니다.각 유효성 검사 메서드를 수 있지만 모든 이름을 가질 형식의 매개 변수가 하나 있습니다 ValidationContext.

    와 하나 이상의 접두사가 있어야 합니다. ValidationMethod 특성:

    [ValidationMethod (ValidationCategories.Open | ValidationCategories.Save | ValidationCategories.Menu ) ]
    

    ValidationCategories 메서드가 실행 되는 시기를 지정 합니다.

예를 들면 다음과 같습니다.

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

이 코드에 대 한 다음 사항을 확인 합니다.

  • 도메인 클래스 또는 도메인 관계에 유효성 검사 메서드를 추가할 수 있습니다.이러한 종류의 코드에는 Dsl\Generated Code\Domain*.cs.

  • 각 유효성 검사 메서드를 해당 클래스와 해당 서브 클래스의 모든 인스턴스에 적용 됩니다.도메인 관계의 경우 각 인스턴스는 두 모델 요소 사이의 링크입니다.

  • 유효성 검사 메서드가 지정 된 순서로 적용 되지 않습니다 하 고 예측 가능한 임의의 순서로 클래스 인스턴스의 각 메서드에 적용 되지 않습니다.

  • 이 일관성 없는 결과가 발생할 수 있기 때문에 저장소 콘텐츠를 업데이트 하는 유효성 검사 메서드를 일반적으로 잘못 된 구현 방법입니다.호출 하 여 오류 메서드를 보고 해야 합니다 대신, context.LogError, LogWarning 또는 LogInfo.

  • LogError 호출에서 모델 요소 또는 사용자가 오류 메시지를 두 번 클릭 하면 선택 되는 관계 링크 목록을 제공할 수 있습니다.

  • 정보 모델에 프로그램 코드를 읽는 방법에 대 한 자세한 내용은 프로그램 코드에서 모델 탐색 및 업데이트.

이 예제에서는 다음과 같은 도메인 모델에 적용 됩니다.자식 및 부모 명명 된 역할의 ParentsHaveChildren 관계를 갖고 있습니다.

DSL 정의 다이어그램 - 패밀리 트리 모델

유효성 검사 범주

에 있는 ValidationMethod 특성에서 지정한 유효성 검사 메서드를 실행 해야 하는 경우.

범주

실행

Menu

때 사용자가 유효성 검사 메뉴 명령을 호출 합니다.

Open

모델 파일이 열립니다.

Save

때 파일을 저장 합니다.유효성 검사 오류가 있으면 사용자가 저장을 취소 하는 옵션이 주어 집니다 작업입니다.

Load

때 파일을 저장 합니다.이 종류의 방법 중에서 오류가 있으면 사용자가 해당 파일을 다시 열고 가능한 아닐 수 경고가 표시 됩니다.

이 범주를 사용 하면 테스트 하는 유효성 검사 메서드를 중복된 이름이 나 Id를 또는 로드 오류가 발생할 수 있는 다른 조건에 대 한.

Custom

때 ValidateCustom 메서드가 호출 됩니다.이 범주에 대 한 유효성 검사 프로그램 코드 에서만 호출할 수 있습니다.

자세한 내용은 사용자 지정 유효성 검사 범주의.

적절 한 유효성 검사 메서드를

종종 다른 종류의 유효성 검사 메서드를 배치 하 여 같은 효과 얻을 수 있습니다.예를 들어, Person 클래스는 ParentsHaveChildren 관계를 대신 하는 메서드를 추가 하 고, 링크를 통해 반복 하 여:

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

유효성 검사 제약 조건이 집계 합니다. 예상한 순서 유효성 검사를 적용 하려면 이러한 루트 요소 모델의 소유자 클래스에 단일 유효성 검사 메서드를 정의 합니다.이 기법은 또한 하나의 메시지에 여러 오류 보고서를 집계 수 있습니다.

단점이 되는 결합 된 방법을 보다 쉽게 관리할 수 있습니다 및 제약 조건에 모두 동일 합니다 ValidationCategories.따라서 각 제약 조건은 별도 메서드를 가능 하면 유지할 것이 좋습니다.

컨텍스트 캐시의 값을 전달 합니다. Context 매개 변수는 임의의 값을 넣을 수 있습니다 사전이 있습니다.사전 유효성 검사 실행의 수명 동안 유지 됩니다.특정 유효성 검사 메서드 수 있습니다, 그리고 예를 들어, 오류 개수에서 보관 하 여 반복 된 메시지와 오류 창을 초과 방지 합니다.예를 들면 다음과 같습니다.

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

복합성의 유효성 검사

최소 복합성 검사를 위한 유효성 검사 메서드를 DSL에 대 한 자동으로 생성 됩니다.코드를 작성 하려면 Dsl\Generated Code\MultiplicityValidation.cs.유효성 검사를 사용 하면 이러한 방법을 적용은 Editor\Validation DSL 탐색기에서에서 노드를 합니다.

1로 도메인 관계 역할의 복합성을 설정 하면.. * 또는 1, 하지만 사용자가 만들지 않습니다이 관계에 대 한 링크의 유효성 검사 오류 메시지가 나타납니다.

경우를 DSL 및 마을, 사람과 관계는 PersonLivesInTown 관계를 예를 들어, 클래스 1.. * 마을 역할에 없는 마을 있는 각 사용자에 대해 오류 메시지가 나타납니다.

프로그램 코드에서 유효성 검사를 실행합니다.

유효성 검사에 액세스 하거나 Validationcontroller를 만들어 실행할 수 있습니다.오류 창에 사용자에 게 표시 되는 오류 다이어그램을 Docdata에 연결 된 Validationcontroller를 사용 합니다.예를 들어, 메뉴 명령, 작성 하는 경우 CurrentDocData.ValidationController 명령 집합 클래스에서 사용할 수 있습니다.

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

자세한 내용은 방법: 바로 가기 메뉴에 명령 추가를 참조하십시오.

개별 유효성 검사 컨트롤러를 만들어 오류를 직접 관리할 수도 있습니다.예를 들면 다음과 같습니다.

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

변경 될 때 유효성 검사를 실행 합니다.

모델이 유효 하지 않게 되는 경우 사용자가 즉시 경고가 나타납니다 있는지 확인 하려는 경우 유효성 검사를 실행 하는 저장소 이벤트를 정의할 수 있습니다.저장소 이벤트에 대 한 자세한 내용은 이벤트 처리기로 모델 외부의 변경 내용 전파.

유효성 검사 코드에 사용자 지정 코드 파일에 추가 DslPackage 프로젝트 다음과 유사한 내용이 있습니다.이 코드를 사용 하 여 ValidationController 문서에 첨부 된.이 컨트롤러에 유효성 검사 오류가 표시 됩니다의 Visual Studio 오류 목록입니다.

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

링크 또는 요소에 명령 취소 나 명령 복구 작업 후 처리기가 호출 됩니다.

사용자 지정 유효성 검사 범주

열기, 메뉴 등의 표준 유효성 검사 범주 이외에 고유한 범주를 정의할 수 있습니다.이러한 범주의 프로그램 코드에서 호출할 수 있습니다.사용자가 직접 호출할 수 없습니다.

사용자 지정 범주에 대 한 일반적인 사용 조건은 특정 도구는 모델을 만족 시키는 지 여부를 테스트 하는 범주 정의 됩니다.

유효성 검사 메서드를 특정 범주에 추가 하려면 다음과 같이 특성을 접두사:

[ValidationMethod(CustomCategory = "PreconditionsForGeneratePartsList")]
[ValidationMethod(ValidationCategory.Menu)] 
private void TestForCircularLinks(ValidationContext context) 
{...}

[!참고]

많은 사용 하 여 메서드를 접두사로 붙일 수 있습니다 [ValidationMethod()] 특성을 원하는 대로.사용자 지정 및 표준 범주에 메서드를 추가할 수 있습니다.

사용자 지정 유효성 검사를 호출.

// Invoke all validation methods in a custom category: 
validationController.ValidateCustom
  (store, // or a list of model elements
   "PreconditionsForGeneratePartsList");

대체 유효성 검사 방법

제약 조건 유효성 검사 오류를 보고 하지만 모델을 변경 하지 마십시오.모델이 잘못 되는 것을 방지 하려는 경우 다른 방법을 사용할 수 있습니다.

그러나 이러한 방법은 권장 하지 않습니다.잘못 된 모델을 수정 하는 방법을 결정할 수 있도록 하는 것이 좋습니다.

모델 유효성을 복원 하 여 변경 내용을 조정 합니다. 예를 들어, 사용자가 위의 최대 허용된 하는 속성을 설정 하는 경우 속성이 최대값으로 재설정할 수 있습니다.이 작업을 수행 하는 규칙을 정의 합니다.자세한 내용은 규칙으로 모델 내부의 변경 내용 전파을 참조하십시오.

에 대 한 올바르지 않은 변경 시도 하면 트랜잭션을 롤백하십시오. 또한이 위해 규칙을 정의할 수 있습니다 있지만 경우에 따라서는 속성 처리기를 재정의 하는 것이 가능 OnValueChanging(), 또는 같은 메서드를 재정의 하 OnDeleted(). 트랜잭션을 사용 this.Store.TransactionManager.CurrentTransaction.Rollback(). 에 대 한 자세한 내용은 참조 하십시오. 도메인 속성 값 변경 처리기.

주의 정보주의

사용자 변경 조정 되었습니다 또는 롤백될 것 알고 있어야 합니다.예를 들어, 사용System.Windows.Forms.MessageBox.Show("message").

참고 항목

개념

프로그램 코드에서 모델 탐색 및 업데이트

이벤트 처리기로 모델 외부의 변경 내용 전파