방법: 트랜잭션을 사용하여 모델 업데이트 연결

Visual Studio Ultimate에서 UML 디자이너에 대한 확장을 정의하는 경우 여러 변경 내용을 연결된 실행 취소 컨텍스트라는 단일 트랜잭션으로 그룹화할 수 있습니다.

기본적으로 코드에서 모델에 대해 변경하는 각 내용은 사용자가 개별적으로 실행 취소할 수 있습니다. 예를 들어 두 UML 클래스의 이름을 서로 바꾸는 메뉴 명령을 정의하는 경우 사용자가 이 명령을 호출한 후 단일 실행 취소를 수행할 수 있습니다. 이렇게 하면 한 이름에 대한 변경 내용만 실행 취소되고 다른 이름은 취소되지 않으므로 모델은 의도하지 않은 상태가 됩니다.

이런 문제가 발생하지 않도록 하기 위해 코드에서 일련의 변경 내용을 하나의 트랜잭션 내에서 수행할 수 있습니다. 이렇게 하면 사용자는 단일 변경 내용으로 인식하게 됩니다. 이후 실행 취소 명령을 수행하면 전체 변경 내용이 실행 취소됩니다.

또한 예외를 throw하거나 트랜잭션을 중단하여 전체 변경 내용 집합을 부분적으로 실행 취소할 수 있다는 이점도 있습니다.

변경 내용을 단일 트랜잭션으로 그룹화하려면

프로젝트 참조에 다음 .NET 어셈블리가 포함되어야 합니다.

Microsoft.VisualStudio.Modeling.Sdk.12.0.dll

다음과 같이 클래스 내에서 ILinkedUndoContext 형식의 가져온 속성을 선언합니다.

using Microsoft.VisualStudio.Modeling.ExtensionEnablement;

...

class … {

[Import]

public ILinkedUndoContext LinkedUndoContext { get; set; }

다음과 같이 모델을 수정하는 메서드에서 변경 내용을 트랜잭션에 포함합니다.

using (ILinkedUndoTransaction transaction =

LinkedUndoContext.BeginTransaction("my updates"))

{

// code to update model elements or shapes goes here

transaction.Commit();

}

다음 내용을 참고하십시오.

  • 트랜잭션의 끝에 항상 Commit()을 포함해야 합니다. 트랜잭션을 커밋하지 않고 삭제하면 해당 트랜잭션이 롤백됩니다. 즉, 트랜잭션을 시작할 때의 상태로 모델이 복원됩니다.

  • 트랜잭션 내에서 catch되지 않은 예외가 발생하면 해당 트랜잭션이 롤백됩니다. 트랜잭션의 using 블록을 try…catch 블록 내에 포함하는 것은 자주 사용되는 패턴입니다.

  • 트랜잭션을 중첩시킬 수 있습니다.

  • 공백이 아닌 이름을 BeginTransaction()에 제공할 수 있습니다.

  • UML 모델 저장소만 이러한 트랜잭션의 영향을 받습니다. 모델링 트랜잭션은 변수, 외부 저장소(예: 파일과 데이터베이스), 레이어 다이어그램, 코드에서 생성된 시퀀스 다이어그램 및 코드 모델에 영향을 주지 않습니다.

 예제

    using Microsoft.VisualStudio.Modeling.ExtensionEnablement;
    using Microsoft.VisualStudio.Uml.Interfaces;
    using Microsoft.VisualStudio.Uml.Classes;
    using Microsoft.VisualStudio.Uml.Extensions;
    using System.Linq;
    using System.ComponentModel.Composition;
 ...
  [Import]
  public ILinkedUndoContext LinkedUndoContext { get; set; }

  /// <summary>
  /// Swap the names of the currently selected elements.
  /// </summary>
  public void Execute(IMenuCommand command)
  {
    var selectedShapes =
      Context.CurrentDiagram.GetSelectedShapes<IClassifier>();
    if (selectedShapes.Count() < 2) return;
    IClassifier firstElement = selectedShapes.First().Element;
    IClassifier lastElement = selectedShapes.Last().Element;
    string firstName = firstElement.Name;
    // Perform changes inside a transaction so that undo
    // works as a single change.
    using (ILinkedUndoTransaction transaction = 
      LinkedUndoContext.BeginTransaction("Swap names"))
    {
        firstElement.Name = lastElement.Name;
        lastElement.Name = firstName;
        transaction.Commit();
    }
 }

참고 항목

개념

UML API를 사용한 프로그래밍

방법: 모델링 다이어그램의 메뉴 명령 정의

UML 모델 및 다이어그램 확장