Propagation de modifications dans le modèle par des règlesRules Propagate Changes Within the Model

Vous pouvez créer une règle de magasin pour propager une modification d’un élément à un autre dans la visualisation et modélisation de kit de développement logiciel (SDK) VISUALIZATION.You can create a store rule to propagate a change from one element to another in Visualization and Modeling SDK (VMSDK). En cas de modification à un élément dans le Store, les règles sont planifiées pour être exécutée, généralement lors de la transaction externe est validée.When a change occurs to any element in the Store, rules are scheduled to be executed, usually when the outermost transaction is committed. Il existe différents types de règles pour différents types d’événements, comme l’ajout d’un élément ou sa suppression.There are different types of rules for different kinds of events, such as adding an element, or deleting it. Vous pouvez attacher des règles à des types d’éléments, des formes ou des diagrammes.You can attach rules to specific types of elements, shapes, or diagrams. Nombreuses fonctionnalités intégrées sont définies par les règles : par exemple, règles garantissent qu’un diagramme est mis à jour quand le modèle change.Many built-in features are defined by rules: for example, rules ensure that a diagram is updated when the model changes. Vous pouvez personnaliser votre langage spécifique à un domaine en ajoutant vos propres règles.You can customize your domain-specific language by adding your own rules.

Règles de Store sont particulièrement utiles pour les modifications de propagation des modifications à l’intérieur de la banque - autrement dit, des propriétés pour les éléments de modèle, des relations, des formes ou des connecteurs et leur domaine.Store rules are particularly useful for propagating changes inside the store - that is, changes to model elements, relationships, shapes or connectors, and their domain properties. Les règles ne s’exécutent pas lorsque l’utilisateur appelle les commandes d’annulation ou de rétablissement.Rules do not run when the user invokes the Undo or Redo commands. Au lieu de cela, le Gestionnaire de transactions permet de s’assurer que le magasin de contenu est restauré à l’état correct.Instead, the transaction manager makes sure that the store contents are restored to the correct state. Si vous souhaitez propager les modifications apportées aux ressources en dehors du magasin, utilisez les événements de Store.If you want to propagate changes to resources outside the store, use Store Events. Pour plus d’informations, consultez gestionnaires propager les modifications en dehors le modèle d’événement.For more information, see Event Handlers Propagate Changes Outside the Model.

Par exemple, supposons que vous souhaitez spécifier que chaque fois que l’utilisateur (ou votre code) crée un nouvel élément de type ExampleDomainClass, un élément supplémentaire d’un autre type est créé dans une autre partie du modèle.For example, suppose that you want to specify that whenever the user (or your code) creates a new element of type ExampleDomainClass, an additional element of another type is created in another part of the model. Vous pouvez écrire un AddRule et associez-le à ExampleDomainClass.You could write an AddRule and associate it with ExampleDomainClass. Vous devez écrire le code dans la règle pour créer l’élément supplémentaire.You would write code in the rule to create the additional element.

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.Modeling;

namespace ExampleNamespace
{
 // Attribute associates the rule with a domain class:
 [RuleOn(typeof(ExampleDomainClass), FireTime=TimeToFire.TopLevelCommit)]
 // The rule is a class derived from one of the abstract rules:
 class MyAddRule : AddRule
 {
  // Override the abstract method:
  public override void ElementAdded(ElementAddedEventArgs e)
  {
    base.ElementAdded(e);
    ExampleDomainClass element = e.ModelElement;
    Store store = element.Store;
    // Ignore this call if we're currently loading a model:
    if (store.TransactionManager.CurrentTransaction.IsSerializing)
       return;

    // Code here propagates change as required - for example:
      AnotherDomainClass echo = new AnotherDomainClass(element.Partition);
      echo.Name = element.Name;
      echo.Parent = element.Parent;
    }
  }
 // The rule must be registered:
 public partial class ExampleDomainModel
 {
   protected override Type[] GetCustomDomainModelTypes()
   {
     List<Type> types = new List<Type>(base.GetCustomDomainModelTypes());
     types.Add(typeof(MyAddRule));
     // If you add more rules, list them here.
     return types.ToArray();
   }
 }
}

Note

Le code d’une règle doit modifier l’état uniquement des éléments à l’intérieur du Store ; Autrement dit, la règle doit modifier uniquement les éléments de modèle, les relations, formes, connecteurs, diagrammes ou leurs propriétés.The code of a rule should change the state only of elements inside the Store; that is, the rule should change only model elements, relationships, shapes, connectors, diagrams, or their properties. Si vous souhaitez propager les modifications apportées aux ressources en dehors du magasin, définir des événements Store.If you want to propagate changes to resources outside the store, define Store Events. Pour plus d’informations, consultez gestionnaires propager les modifications en dehors le modèle d’événementFor more information, see Event Handlers Propagate Changes Outside the Model

Pour définir une règleTo define a rule

  1. Définir la règle comme une classe préfixé avec le RuleOn attribut.Define the rule as a class prefixed with the RuleOn attribute. L’attribut associe la règle à une de vos classes de domaine, relations ou éléments de diagramme.The attribute associates the rule with one of your domain classes, relationships, or diagram elements. La règle sera appliquée à chaque instance de cette classe, ce qui peut être abstraite.The rule will be applied to every instance of this class, which may be abstract.

  2. Enregistrer la règle en l’ajoutant à l’ensemble retourné par GetCustomDomainModelTypes() dans votre classe de modèle de domaine.Register the rule by adding it to the set returned by GetCustomDomainModelTypes() in your domain model class.

  3. Dérivez la classe de règle d’une des classes abstraites de règle et écrire le code de la méthode d’exécution.Derive the rule class from one of the abstract Rule classes, and write the code of the execution method.

    Les sections suivantes décrivent ces étapes plus en détail.The following sections describe these steps in more detail.

Pour définir une règle sur une classe de domaineTo define a rule on a domain class

  • Dans un fichier de code personnalisé, définissez une classe et faites-la précéder le RuleOnAttribute attribut :In a custom code file, define a class and prefix it with the RuleOnAttribute attribute:

    [RuleOn(typeof(ExampleElement),
         // Usual value - but required, because it is not the default:
         FireTime = TimeToFire.TopLevelCommit)]
    class MyRule ...
    
  • Le type d’objet dans le premier paramètre peut être une classe de domaine, la relation de domaine, la forme, la connecteur ou diagramme.The subject type in the first parameter can be a domain class, domain relationship, shape, connector, or diagram. En règle générale, vous appliquez des règles aux relations et classes de domaine.Usually, you apply rules to domain classes and relationships.

    Le FireTime est généralement TopLevelCommit.The FireTime is usually TopLevelCommit. Cela garantit que la règle est exécutée uniquement une fois que les principales modifications de la transaction ont été apportées.This ensures that the rule is executed only after all the primary changes of the transaction have been made. Les alternatives sont Inline, qui exécute la règle peu après la modification ; et du LocalCommit, qui s’exécute à la règle à la fin de la transaction actuelle (qui ne peut pas être plus à l’extérieur).The alternatives are Inline, which executes the rule soon after the change; and LocalCommit, which executes the rule at the end of the current transaction (which might not be the outermost). Vous pouvez également définir la priorité d’une règle à affecter son classement dans la file d’attente, mais il s’agit d’une méthode non fiable d’atteindre le résultat que vous avez besoin.You can also set the priority of a rule to affect its ordering in the queue, but this is an unreliable method of achieving the result you require.

  • Vous pouvez spécifier une classe abstraite comme type d’objet.You can specify an abstract class as the subject type.

  • La règle s’applique à toutes les instances de la classe d’objet.The rule applies to all instances of the subject class.

  • La valeur par défaut FireTime est TimeToFire.TopLevelCommit.The default value for FireTime is TimeToFire.TopLevelCommit. Cela provoque la règle à exécuter lorsque la transaction externe est validée.This causes the rule to be executed when the outermost transaction is committed. Une alternative consiste à TimeToFire.Inline.An alternative is TimeToFire.Inline. Cela provoque la règle doit être exécuté peu après l’événement de déclenchement.This causes the rule to be executed soon after the triggering event.

Pour enregistrer la règleTo register the rule

  • Ajouter votre classe de règle à la liste des types retournés par GetCustomDomainModelTypes dans votre modèle de domaine :Add your rule class to the list of types returned by GetCustomDomainModelTypes in your domain model:

    public partial class ExampleDomainModel
     {
       protected override Type[] GetCustomDomainModelTypes()
       {
         List<Type> types = new List<Type>(base.GetCustomDomainModelTypes());
         types.Add(typeof(MyAddRule));
         // If you add more rules, list them here.
         return types.ToArray();
       }
     }
    
  • Si vous n’êtes pas sûr du nom de votre classe de modèle de domaine, regardez dans le fichier Dsl\GeneratedCode\DomainModel.csIf you are not sure of the name of your domain model class, look inside the file Dsl\GeneratedCode\DomainModel.cs

  • Écrire ce code dans un fichier de code personnalisé dans votre projet DSL.Write this code in a custom code file in your DSL project.

Pour écrire le code de la règleTo write the code of the rule

  • Dérivez la classe de règle d’une des classes de base suivantes :Derive the rule class from one of the following base classes:

    Classe de baseBase class DéclencheurTrigger
    AddRule Un élément, un lien ou une forme est ajoutée.An element, link, or shape is added.

    Cela permet de détecter de nouvelles relations, en plus de nouveaux éléments.Use this to detect new relationships, in addition to new elements.
    ChangeRule Une valeur de propriété de domaine est modifiée.A domain property value is changed. L’argument de méthode fournit les valeurs anciennes et nouvelles.The method argument provides the old and new values.

    Pour les formes, cette règle est déclenchée lorsque l’intégrée AbsoluteBounds des modifications de propriété, si la forme est déplacée.For shapes, this rule is triggered when the built-in AbsoluteBounds property changes, if the shape is moved.

    Dans de nombreux cas, il est plus pratique substituer OnValueChanged ou OnValueChanging dans le Gestionnaire de propriétés.In many cases, it is more convenient to override OnValueChanged or OnValueChanging in the property handler. Ces méthodes sont appelées immédiatement avant et après la modification.These methods are called immediately before and after the change. En revanche, la règle s’exécute généralement à la fin de la transaction.By contrast, the rule usually runs at the end of the transaction. Pour plus d’informations, consultez gestionnaires de modification de valeur de propriété de domaine.For more information, see Domain Property Value Change Handlers. Remarque : cette règle n’est pas déclenchée lorsqu’un lien est créé ou supprimé.Note: This rule is not triggered when a link is created or deleted. En revanche, écrire un AddRule et un DeleteRule pour la relation de domaine.Instead, write an AddRule and a DeleteRule for the domain relationship.
    DeletingRule Déclenché lorsqu’un élément ou un lien est sur le point d’être supprimé.Triggered when an element or link is about to be deleted. La propriété ModelElement.IsDeleting vaut jusqu'à la fin de la transaction.The property ModelElement.IsDeleting is true until the end of the transaction.
    DeleteRule Effectuée lorsqu’un élément ou un lien a été supprimé.Performed when an element or link has been deleted. La règle est exécutée une fois que toutes les autres règles ont été exécutées, y compris DeletingRules.The rule is executed after all other rules have been executed, including DeletingRules. ModelElement.IsDeleting a la valeur false et ModelElement.IsDeleted a la valeur true.ModelElement.IsDeleting is false, and ModelElement.IsDeleted is true. Pour permettre une annulation ultérieure, l’élément n'est pas réellement supprimé de la mémoire, mais il est supprimé de Store.ElementDirectory.To allow for a subsequent Undo, the element is not actually removed from the memory, but it is removed from Store.ElementDirectory.
    MoveRule Un élément est déplacé à partir de la partition d’un magasin vers un autre.An element is moved from one store partition to another.

    (Notez que cela n’est pas liée à la position d’une forme de graphique).(Notice that this is not related to the graphical position of a shape.)
    RolePlayerChangeRule Cette règle s’applique uniquement aux relations de domaine.This rule applies only to domain relationships. Elle est déclenchée si vous affectez explicitement un élément de modèle à chaque extrémité d’un lien.It is triggered if you explicitly assign a model element to either end of a link.
    RolePlayerPositionChangeRule Déclenché lorsque l’ordre des liens vers ou à partir d’un élément est modifié à l’aide des méthodes MoveBefore ou MoveToIndex sur un lien.Triggered when the ordering of links to or from an element is changed using the MoveBefore or MoveToIndex methods on a link.
    TransactionBeginningRule Exécuté lorsqu’une transaction est créée.Executed when a transaction is created.
    TransactionCommittingRule Exécutée lorsque la transaction est sur le point d’être validée.Executed when the transaction is about to be committed.
    TransactionRollingBackRule Exécutée lorsque la transaction est sur le point d’être restaurée.Executed when the transaction is about to be rolled back.
  • Chaque classe a une méthode que vous substituez.Each class has a method that you override. Type override dans votre classe pour la détection.Type override in your class to discover it. Le paramètre de cette méthode identifie l’élément qui est en cours de modification.The parameter of this method identifies the element that is being changed.

    Notez les points suivants concernant les règles :Notice the following points about rules:

  1. L’ensemble de modifications dans une transaction peut déclencher plusieurs règles.The set of changes in a transaction might trigger many rules. En règle générale, les règles sont exécutées lorsque la transaction externe est validée.Usually, the rules are executed when the outermost transaction is committed. Ils sont exécutés dans un ordre non spécifié.They are executed in an unspecified order.

  2. Une règle est toujours exécutée dans une transaction.A rule is always executed inside a transaction. Par conséquent, vous n’êtes pas obligé de créer une nouvelle transaction pour apporter des modifications.Therefore, you do not have to create a new transaction to make changes.

  3. Les règles ne sont pas exécutées lorsqu’une transaction est restaurée, ou lors de l’annulation ou rétablissement des opérations.Rules are not executed when a transaction is rolled back, or when the Undo or Redo operations are performed. Ces opérations Réinitialiser tout le contenu du Store à son état précédent.These operations reset all the content of the Store to its previous state. Par conséquent, si votre règle modifie l’état de quoi que ce soit à l’extérieur du Store, il ne peut pas conserver dans synchronism avec le Store contenu.Therefore, if your rule changes the state of anything outside the Store, it might not keep in synchronism with the Store content. Pour mettre à jour d’état à l’extérieur du Store, il est préférable d’utiliser des événements.To update state outside the Store, it is better to use Events. Pour plus d’informations, consultez gestionnaires propager les modifications en dehors le modèle d’événement.For more information, see Event Handlers Propagate Changes Outside the Model.

  4. Certaines règles sont exécutées lorsqu’un modèle est chargé à partir du fichier.Some rules are executed when a model is loaded from file. Pour déterminer si le chargement ou l’enregistrement est en cours d’exécution, utilisez store.TransactionManager.CurrentTransaction.IsSerializing.To determine whether loading or saving is in progress, use store.TransactionManager.CurrentTransaction.IsSerializing.

  5. Si le code de votre règle crée plusieurs déclencheurs de règle, ils seront ajoutés à la fin de la liste de déclenchement et seront exécutées avant la fin de la transaction.If the code of your rule creates more rule triggers, they will be added to the end of the firing list, and will be executed before the transaction completes. DeletedRules sont exécutés après toutes les autres règles.DeletedRules are executed after all other rules. Une règle peut exécutées plusieurs fois dans une transaction, une fois pour chaque modification.One rule can run many times in a transaction, one time for each change.

  6. Pour passer des informations à destination et à partir de règles, vous pouvez stocker les informations contenues dans le TransactionContext.To pass information to and from rules, you can store information in the TransactionContext. Il s’agit simplement d’un dictionnaire qui est conservé pendant la transaction.This is just a dictionary that is maintained during the transaction. Il est supprimé lorsque la transaction se termine.It is disposed when the transaction ends. Les arguments d’événement dans chaque règle de fournissent un accès à celui-ci.The event arguments in each rule provide access to it. N’oubliez pas que les règles ne sont pas exécutées dans un ordre prévisible.Remember that rules are not executed in a predictable order.

  7. Utiliser les règles après avoir étudié les autres alternatives.Use rules after considering other alternatives. Par exemple, si vous souhaitez mettre à jour une propriété lorsqu’une valeur change, envisagez d’utiliser une propriété calculée.For example, if you want to update a property when a value changes, consider using a calculated property. Si vous souhaitez limiter la taille ou l’emplacement d’une forme, utilisez un BoundsRule.If you want to constrain the size or location of a shape, use a BoundsRule. Si vous souhaitez répondre à une modification dans une valeur de propriété, ajoutez un OnValueChanged gestionnaire à la propriété.If you want to respond to a change in a property value, add an OnValueChanged handler to the property. Pour plus d’informations, consultez réponse en cours à et propagation des modifications.For more information, see Responding to and Propagating Changes.

ExempleExample

L’exemple suivant met à jour une propriété lorsqu’une relation de domaine est instanciée pour lier deux éléments.The following example updates a property when a domain relationship is instantiated to link two elements. La règle est déclenchée non seulement lorsque l’utilisateur crée un lien dans un diagramme, mais également si le code de programme crée un lien.The rule will be triggered not only when the user creates a link on a diagram, but also if program code creates a link.

Pour tester cet exemple, créez un DSL à l’aide du modèle de solution flux de tâches et insérez le code suivant dans un fichier dans le projet Dsl.To test this example, create a DSL using the Task Flow solution template, and insert the following code in a file in the Dsl project. Générer et exécuter la solution et ouvrez l’exemple de fichier dans le projet de débogage.Build and run the solution, and open the Sample file in the Debugging project. Dessinez un lien de commentaire entre une zone de commentaire et un élément de flux.Draw a Comment Link between a Comment shape and a flow element. Le texte dans les modifications de commentaire au rapport sur l’élément plus récente que vous avez connectée à.The text in the comment changes to report on the most recent element that you have connected it to.

Dans la pratique, vous devez généralement écrire un DeleteRule pour chaque AddRule.In practice, you would usually write a DeleteRule for every AddRule.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.Modeling;

namespace Company.TaskRuleExample
{

  [RuleOn(typeof(CommentReferencesSubjects))]
  public class RoleRule : AddRule
  {

    public override void ElementAdded(ElementAddedEventArgs e)
    {
      base.ElementAdded(e);
      CommentReferencesSubjects link = e.ModelElement as CommentReferencesSubjects;
      Comment comment = link.Comment;
      FlowElement subject = link.Subject;
      Transaction current = link.Store.TransactionManager.CurrentTransaction;
      // Don't want to run when we're just loading from file:
      if (current.IsSerializing) return;
      comment.Text = "Flow has " + subject.FlowTo.Count + " outgoing connections";
    }

  }

  public partial class TaskRuleExampleDomainModel
  {
    protected override Type[] GetCustomDomainModelTypes()
    {
      List<Type> types = new List<Type>(base.GetCustomDomainModelTypes());
      types.Add(typeof(RoleRule));
      return types.ToArray();
    }
  }

}

Voir aussiSee Also