Comment : lier des mises à jour de modèles à l'aide de transactions
Lorsque vous définissez une extension aux concepteurs UML dans Visual Studio Ultimate, vous pouvez regrouper plusieurs modifications dans une transaction unique appelée contexte d'annulation lié.
Par défaut, chaque modification que votre code apporte à un modèle peut être annulée séparément par l'utilisateur. Par exemple, si vous définissez une commande de menu qui intervertit les noms de deux classes UML, un utilisateur peut appeler la commande et exécuter une annulation unique. Cela annulerait la modification apportée à un nom, mais pas celle concernant l'autre, laissant ainsi votre modèle dans un état non souhaité.
Pour éviter une telle situation, votre code peut exécuter une série de modifications dans une transaction. Ainsi, les modifications présentent l'aspect d'une modification unique pour l'utilisateur. Une commande d'annulation consécutive annulera toute la série.
Un avantage supplémentaire est que votre code peut annuler un ensemble de modifications partiellement complet en levant une exception ou en abandonnant la transaction.
Pour regrouper plusieurs modifications dans une transaction unique
Assurez-vous que les références de votre projet incluent cet assembly .NET :
Microsoft.VisualStudio.Modeling.Sdk.10.0.dll
Dans votre classe, déclarez une propriété importée dont le type est ILinkedUndoContext :
using Microsoft.VisualStudio.Modeling.ExtensionEnablement;
...
class … {
[Import]
public ILinkedUndoContext LinkedUndoContext { get; set; }
Dans une méthode qui modifie le modèle, insérez vos modifications dans une transaction :
using (ILinkedUndoTransaction transaction =
LinkedUndoContext.BeginTransaction("my updates"))
{
// code to update model elements or shapes goes here
transaction.Commit();
}
Notez les points suivants :
Vous devez toujours inclure Commit() à la fin de la transaction. Si une transaction est supprimée sans avoir été validée, la transaction sera alors restaurée. Autrement dit, l'état du modèle sera restauré tel qu'il était au début de la transaction.
Si une exception n'est pas interceptée dans la transaction, celle-ci sera alors restaurée. Il s'agit d'un modèle fréquemment utilisé pour insérer le bloc de transaction using dans un bloc try…catch.
Vous pouvez imbriquer des transactions.
Vous pouvez fournir un nom non vide à BeginTransaction().
Seul le magasin de modèles UML est affecté par ces transactions. Les transactions de modélisation n'affectent pas les éléments suivants : variables, magasins externes comme les fichiers et les bases de données, les diagrammes de couches, les diagrammes de séquence générés à partir du code, ainsi que les modèles de code.
Exemple
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();
}
}
Voir aussi
Autres ressources
Programmation à l'aide de l'API UML
Comment : définir une commande de menu sur un diagramme de modélisation