Практическое руководство. Редактирование схем последовательностей с помощью API UML

Взаимодействие — это последовательность сообщений между набором линий жизни.Взаимодействие отображается на схеме последовательностей.

Полные сведения об интерфейсе API см. в разделе Microsoft.VisualStudio.Uml.Interactions.)

Более общие сведения о создании команд и обработчиков жестов UML-схем см. в разделе Практическое руководство. Определение команды меню на схеме моделирования.

Базовый код

Ee349042.collapse_all(ru-ru,VS.110).gifИмпорты пространства имен

Необходимо включить следующие операторы using.

using Microsoft.VisualStudio.Uml.Classes;
   // for basic UML types such as IPackage
using Microsoft.VisualStudio.Uml.Interactions;
   // for interaction types
using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Uml;
   // to create elements and use additional functions

Для создания команд меню и обработчиков жестов также потребуется следующее.

using System.ComponentModel.Composition; 
   // for Import and Export
using Microsoft.VisualStudio.Modeling.ExtensionEnablement;
   // for ICommandExtension
using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Presentation;
   // for diagrams and context

Дополнительные сведения см. в разделе Практическое руководство. Определение команды меню на схеме моделирования.

Ee349042.collapse_all(ru-ru,VS.110).gifПолучение контекста

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

    [SequenceDesignerExtension]
    [Export(typeof(ICommandExtension))]  
    public class MySequenceDiagramCommand : ICommandExtension
    {
        [Import]
        public IDiagramContext Context { get; set; }
        public void QueryStatus (IMenuCommand command)
        {
          ISequenceDiagram sequenceDiagram = 
              Context.CurrentDiagram as ISequenceDiagram;
             ...

Ee349042.collapse_all(ru-ru,VS.110).gifСозданные схемы последовательностей и UML-схемы последовательностей

Существует два вида схем последовательностей: схемы, создаваемые вручную в UML-проекте моделирования, и схемы, создаваемые из программного кода.Свойство UmlMode используется для определения типа используемой схемы последовательностей.

Например, если нужно создать команду меню, видимую только на UML-схеме последовательностей, метод QueryStatus() может содержать следующий оператор.

    command.Enabled = command.Visible = 
          sequenceDiagram != null && sequenceDiagram.UmlMode;

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

    IModel rootModel = sequenceDiagram.ModelStore.Root;
    // !sequenceDiagram.UmlMode == (rootModel == null)

Создание и отображение взаимодействия

Создайте взаимодействие в качестве дочернего элемента пакета или модели.

Например, при создании команды, которая может выполняться на пустой схеме последовательностей, начинать всегда следует с проверки наличия взаимодействия.

public void Execute (IMenuCommand command)
{
    ISequenceDiagram sequenceDiagram = 
         Context.CurrentDiagram as ISequenceDiagram;
    if (sequenceDiagram == null) return;
    // Get the diagram's interaction:
    IInteraction interaction = sequenceDiagram.Interaction;
    // A new sequence diagram might have no interaction:
    if (interaction == null)
    {
       // Get the home package or model of the diagram:
       IPackage parentPackage = sequenceDiagram.GetObject<IPackage>();
       interaction = parentPackage.CreateInteraction();
       // Display the interaction on the sequence diagram:
       sequenceDiagram.Bind(interaction);
    } 

Обновление взаимодействия и его структуры

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

  • ISequenceDiagram.UpdateShapePositions() регулирует положение недавно вставленных или перемещенных фигур, а также фигур, расположенных рядом с ними.

  • ISequenceDiagram.Layout([SequenceDiagramLayoutKinds]) перерисовывает всю схему.Можно использовать этот параметр для задания изменения положения линий жизни, сообщений или и того, и другого.

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

Чтобы не вводить в заблуждение пользователя, выполняющего отмену после данной команды, следует воспользоваться ILinkedUndoTransaction для заключения изменений и окончательных операций Layout()или UpdateShapePositions().Примеры.

using (ILinkedUndoTransaction transaction = LinkedUndoContext.BeginTransaction("create loop"))
{
  Interaction.CreateCombinedFragment(InteractionOperatorKind.Loop, messages);
  Diagram.UpdateShapePositions();
  transaction.Commit();
}

Чтобы воспользоваться ILinkedUndoTransaction, необходимо сделать в классе следующее объявление.

[Import] ILinkedUndoContext LinkedUndoContext { get; set; }

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

Построение взаимодействия

Ee349042.collapse_all(ru-ru,VS.110).gifСоздание линий жизни

ILifeline lifeline = interaction.CreateLifeline();

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

foreach (IConnectableElement part in 
            component.Parts
           .Concat<IConnectableElement>(component.OwnedPorts))
{
   ILifeline lifeline = interaction.CreateLifeline();
   lifeline.Represents = part;
}

Кроме того, если взаимодействие показывает произвольный набор объектов, можно создать свойство или другой IConnectableElement в самом взаимодействии.

ILifeline lifeline = interaction.CreateLifeline();
IProperty property1 = interaction.CreateProperty();
property1.Type = model.CreateInterface();
property1.Type.Name = "Type 1";
lifeline.Represents = property1;

Кроме того, можно задать имя и тип линии жизни, не связывая ее с подключаемым элементом.

ILifeline lifeline = interaction.CreateLifeline();
lifeline.Name = "c1";
lifeline.SetInstanceType("Customer");
System.Diagnostics.Debug.Assert(
           lifeline.GetDisplayName() == "c1:Customer"  );

Ee349042.collapse_all(ru-ru,VS.110).gifСоздание сообщений

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

interaction.CreateMessage( sourceInsertionPoint, 
                           targetInsertionPoint, 
                           MessageKind.Complete, 
                           MessageSort.ASynchCall)

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

interaction.CreateLostFoundMessage(MessageKind.Found, insertionPoint);

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

Метод в Ilifeline

Используется для вставки в этой точке

FindInsertionPointAtTop()

Верх линии жизни.

FindInsertionPointAtBottom()

Низ линии жизни.

FindInsertionPointAfterMessage

(IMessage previous)

Точка, следующая сразу после заданного сообщения.

FindInsertionPointAfterExecutionSpecification

(IExecutionSpecification previous)

Точка может располагаться либо на линии жизни, либо на родительском блоке спецификации выполнения.

FindInsertionPointAfterInteractionUse

(IInteractionUse previous)

Точка, следующая за использованием взаимодействия.

FindInsertionPointAfterCombinedFragment

(ICombinedFragment previous)

Точка, следующая за объединенным фрагментом.

FindInsertionPoint(IExecutionSpecification block)

Верх блока выполнения.

FindInsertionPoint(IInteractionOperand fragment)

Верх операнда в объединенном фрагменте.

При создании сообщений нужно следить за тем, чтобы не определить сообщение, которое может пересечься с другим сообщением.

Ee349042.collapse_all(ru-ru,VS.110).gifСоздание объединенных фрагментов и вариантов использования взаимодействия

Чтобы создать объединенные фрагменты и варианты использования взаимодействия, нужно задать точку вставки на каждой линии жизни, которая должна охватываться элементом.Нужно следить за тем, чтобы не задать набор точек, которые могут пересечься с существующим сообщением или фрагментом.

Interaction.CreateCombinedFragment(InteractionOperatorKind.Loop, 
  Interaction.Lifelines.Select(lifeline => lifeline.FindInsertionPointAtTop()));
Interaction.CreateInteractionUse(
  Interaction.Lifelines.Select(lifeline => lifeline.FindInsertionPointAtTop()));

Кроме того, можно создать объединенный фрагмент, охватывающий существующий набор сообщений.Все сообщения должны иметь в качестве источника одну линию жизни или блок выполнения.

ICombinedFragment cf = Interaction.CreateCombinedFragment(
  InteractionOperatorKind.Loop,
  Interaction.Lifelines.First().GetAllOutgoingMessages());

Объединенный фрагмент всегда создается с одним операндом.Чтобы создать новый операнд, необходимо задать существующий операнд, который необходимо вставить до или после нового, и указать, где именно (до или после) его нужно вставить.

// Create an additional operand before the first
cf.CreateInteractionOperand(cf.Operands.First(), false);
// Create an additional operand after the last:
cf.CreateInteractionOperand(cf.Operands.Last(), true);

Устранение неполадок

Если после внесения изменений не выполнить операцию UpdateShapePositions() или Layout(), фигуры отобразятся на схеме в неправильных положениях.

Большинство других проблем происходит из-за невыравненности точек вставок, т. е. когда новые сообщения или фрагменты пересекаются с другими элементами схемы.Об этом свидетельствует отсутствие изменений на схеме или создание исключения.Иногда исключение не создается до тех пор, пока не выполнена операция UpdateShapePositions() или Layout().

См. также

Ссылки

Microsoft.VisualStudio.Uml.Interactions

Основные понятия

Расширение моделей и схем UML

Практическое руководство. Определение команды меню на схеме моделирования

Практическое руководство. Определение настраиваемого элемента панели элементов моделирования

Практическое руководство. Определение ограничений проверки для моделей UML

Программирование с UML API