Поделиться через


Практическое руководство. Связывание обновлений модели с использованием транзакций

При определении расширения UML-конструкторов в Visual Studio Ultimate можно сгруппировать несколько изменений в одну транзакцию, которая называется связанный контекст отмены.

По умолчанию пользователь может отдельно отменить любое изменение, внесенное в модель с помощью кода.Например, если определяется команда меню, которая меняет местами названия двух UML-классов, пользователь может вызвать команду, а затем произвести отмену одной команды.Это действие позволяет отменить изменения только одного имени, оставляя неизменным другое имя и приводя модель в непреднамеренное состояние.

Во избежание этого с помощью кода можно выполнить ряд изменений в пределах транзакции.В результате для пользователя несколько изменений будут выглядеть как одно изменение.Последующее выполнение команды отмены позволяет отменить весь ряд изменений.

Дополнительное преимущество заключается в том, что с помощью кода можно отменить набор частично завершенных изменений, создав исключение или прервав транзакцию.

Группировка изменений в одну транзакцию

Убедитесь, что ссылки проекта включают следующую сборку .NET.

Microsoft.VisualStudio.Modeling.Sdk.11.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() в конце транзакции.Освобождение незафиксированной транзакции ведет к откату транзакции.Значит, восстанавливается состояние модели до начала транзакции.

  • Если создается исключение, которое не перехватывается внутри транзакции, производится откат транзакции.Очень часто блок 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