Partager via


Propagation de modifications dans le modèle par des règles

Vous pouvez créer une règle du magasin de propager une modification d'un élément à un autre de la Kit de développement logiciel de visualisation et de modélisation (VMSDK).Lorsqu'une modification est apportée à tout élément dans le magasin, les règles sont planifiées à exécuter, généralement lorsque la transaction plus éloignée est validée.Il existe différents types de règles pour différents types d'événements, tels qu'ajouter un élément, ou le supprimer.Vous pouvez joindre des règles à des types spécifiques d'éléments, des formes, ou de diagrammes.De nombreuses fonctionnalités intégrées sont définies par les règles : par exemple, les règles garantissent qu'un diagramme est mis à jour lorsque le modèle change.Vous pouvez personnaliser votre langage spécifique au domaine en ajoutant vos propres règles.

Les règles du magasin sont particulièrement utiles pour propager des modifications à l'intérieur de le magasin - c. autrement dit., modifications apportées aux éléments de modèle, les relations, les formes ou les connecteurs, et leurs propriétés de domaine.Les règles ne s'exécutent pas lorsque l'utilisateur appelle les commandes d'annulation ou de rétablissement.À la place, le gestionnaire de transactions permet de s'assurer que le contenu du magasin est restauré à l'état correct.Si vous souhaitez propager des modifications aux ressources en dehors de le magasin, utilisez les événements de le magasin.Pour plus d'informations, consultez Propagation de modifications en dehors du modèle par des gestionnaires d'événements.

Par exemple, supposons que vous souhaitez spécifier que toutes les fois que l'utilisateur (ou votre code) crée un élément de type ExampleDomainClass, un élément supplémentaire d'un autre type est créé à une autre partie du modèle.Vous pouvez écrire un AddRule et l'associer à ExampleDomainClass.Vous écrirez le code dans la règle de créer l'élément supplémentaire.

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();
   }
 }
}

[!REMARQUE]

Le code d'une règle doit modifier l'état uniquement des éléments à l'intérieur de le magasin ; autrement dit, la règle doit modifier uniquement les éléments de modèle, des relations, des formes, des connecteurs, des schémas, ou leurs propriétés.Si vous souhaitez propager des modifications aux ressources en dehors de le magasin, définissez les événements de le magasin.Pour plus d'informations, consultez Propagation de modifications en dehors du modèle par des gestionnaires d'événements.

pour définir une règle

  1. Définissez la règle en tant que classe préfixée avec l'attribut d' RuleOn .L'attribut associe la règle avec un de vos classes de domaine, les relations, ou éléments du diagramme.la règle sera appliquée à chaque instance de cette classe, qui peut être abstraite.

  2. Enregistrez la règle en l'ajoutant à un ensemble retourné par GetCustomDomainModelTypes() dans votre classe de modèle de domaine.

  3. Dérivez la classe de règle d'une des classes abstraites de règles, et écrivez le code de la méthode d'exécution.

Les sections suivantes décrivent ces étapes en détail.

pour définir une règle sur une classe de domaine

  • dans un fichier de code personnalisé, définissez une classe et préfixez-la avec l'attribut d' RuleOnAttribute :

    [RuleOn(typeof(ExampleElement), 
         // Usual value – but required, because it is not the default:
         FireTime = TimeToFire.TopLevelCommit)] 
    class MyRule ...
    
  • Les envoyés types dans le premier paramètre peut être une classe de domaine, une relation de domaine, une forme, un connecteur, ou un diagramme.Généralement, vous appliquez des règles aux classes et aux relations de domaine.

    FireTime est généralement TopLevelCommit.Cela garantit que la règle est exécutée uniquement après que tous les modifications principaux de la transaction ont été établies.Les possibilités sont inline, qui exécute la règle peu après la modification ; et LocalCommit, qui exécute la règle à la fin de la transaction en cours (qui n'a pas pu être l'intérieur).Vous pouvez également définir la priorité d'une règle d'affecter son l'ordre de la file d'attente, mais il s'agit d'une méthode non fiable d'obtenir le résultat dont vous avez besoin.

  • vous pouvez spécifier une classe abstraite comme type soumis.

  • La règle s'applique à toutes les instances de la classe envoyée.

  • la valeur par défaut pour FireTime est TimeToFire.TopLevelCommit.Cela provoque la règle à exécuter lorsque la transaction plus éloignée est validée.Une autre solution consiste TimeToFire.Inline.Cela provoque la règle d'être exécuté peu après l'événement de déclenchement.

pour enregistrer la règle

  • Ajoutez votre classe de règle à la liste des types retournés par GetCustomDomainModelTypes dans votre modèle de domaine :

    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 ne connaissez pas le nom de votre classe de modèle de domaine, recherchez dans le fichier Dsl\GeneratedCode\DomainModel.cs

  • Entrez ce code dans un fichier de code dans votre projet DÉSOLÉ.

Pour écrire le code de la règle

  • dérivez la classe de règle d'une des classes de base suivantes :

    Classe de base

    Déclencheur

    AddRule

    un élément, un lien, ou une forme est ajouté.

    Utilisez cette option pour détecter de nouvelles relations, en plus de nouveaux éléments.

    ChangeRule

    une valeur de propriété de domaine est modifiée.L'argument de méthode propose les valeurs anciennes et nouvelles.

    Pour les formes, cette règle se déclenche lorsque la propriété d' AbsoluteBounds d'élément change, si la forme est déplacée.

    Dans de nombreux cas, il est plus pratique de substituer OnValueChanged ou OnValueChanging dans le gestionnaire de propriété.Ces méthodes sont appelées immédiatement avant et après la modification.en revanche, la règle fonctionne habituellement à la fin de la transaction.Pour plus d'informations, consultez Gestionnaire de modification de la valeur de propriété du domaine.

    RemarqueRemarque
    Cette règle n'est pas levée lorsqu'un lien est créé ou supprimé.À la place, entrez AddRule et DeleteRule de la relation de domaine.

    DeletingRule

    Déclenché lorsqu'un élément ou un lien est sur le point d'être supprimé.la propriété ModelElement.IsDeleting est vraie jusqu'à la fin de la transaction.

    DeleteRule

    Effectué lorsqu'un élément ou un lien a été supprimé.La règle est exécutée après que tous les autres règles ont été exécutées, y compris DeletingRules.ModelElement.IsDeleting a la valeur false, et ModelElement.IsDeleted est true.Pour permettre l'utilisation d'une annulation suivante, l'élément n'est pas supprimé réellement de la mémoire, mais il est supprimé de Store.ElementDirectory.

    MoveRule

    Un élément est déplacé d'une partition du magasin à un autre.

    (Notez que cela n'est pas lié à la position graphique d'une forme.)

    RolePlayerChangeRule

    Cette règle s'applique uniquement aux relations de domaine.Il est déclenché si vous affectez explicitement un élément de modèle à chaque extrémité d'un lien.

    RolePlayerPositionChangeRule

    Déclenché lorsque le classement des liens vers ou depuis un élément est modifié à l'aide de les méthodes de MoveBefore ou de MoveToIndex sur un lien.

    TransactionBeginningRule

    Exécuté lorsqu'une transaction est créée.

    TransactionCommittingRule

    Effectuée lorsque la transaction est sur le point d'être validée.

    TransactionRollingBackRule

    Effectuée lorsque la transaction est sur le point d'être annulée.

  • Chaque classe contient une méthode que vous substituez.Tapez override de votre classe pour la découverte.le paramètre de cette méthode identifie l'élément qui est modifié.

Notez les points suivants à propos de les règles :

  1. L'ensemble de modifications dans une transaction peut déclencher de nombreuses règles.Généralement, les règles sont exécutées lorsque la transaction plus éloignée est validée.Ils sont exécutés dans un ordre non spécifié.

  2. Une règle est toujours exécutée dans une transaction.Par conséquent, vous ne devez pas créer une transaction pour apporter des modifications.

  3. Les règles ne sont pas exécutées lorsqu'une transaction est annulée, ou lorsqu'une annulation ou les opérations de rétablissement sont exécutées.Ces opérations réinitialisent tout le contenu du magasin à son état précédent.Par conséquent, si votre règle remplace l'état de n'importe quoi à l'extérieur de le magasin, il ne peut pas toujours dans le synchronisme avec le contenu du magasin.Pour mettre à jour l'état à l'extérieur de le magasin, il est recommandé d'utiliser des événements.Pour plus d'informations, consultez Propagation de modifications en dehors du modèle par des gestionnaires d'événements.

  4. Certaines règles sont exécutées lorsqu'un modèle est chargé à partir de le fichier.Pour déterminer si le chargement ou l'enregistrement est en cours, utilisez store.TransactionManager.CurrentTransaction.IsSerializing.

  5. Si le code de votre règle crée plus de déclencheurs de règle, ils seront ajoutés à la fin de la liste de mise à déclencher, et exécutés avant que la transaction se termine.DeletedRules sont exécutés après que tous les autres règles.Une règle peut exécuter plusieurs fois dans une transaction, une fois pour chaque modification.

  6. Pour passer des informations entre des règles, vous pouvez stocker des informations dans TransactionContext.Il s'agit juste d'un dictionnaire qui est maintenu pendant la transaction.Il est supprimé lors de la transaction se termine.Les arguments d'événement dans chaque règle permettent d'accéder à celui-ci.N'oubliez pas que les règles ne sont pas exécutées dans un ordre prévisible.

  7. Règles d'utilisation après avoir pris autre.Par exemple, si vous souhaitez mettre à jour une propriété lorsqu'une valeur change, envisagez d'utiliser une propriété calculée.si vous souhaitez contraindre la taille ou l'emplacement d'une forme, utilisez BoundsRule.Si vous souhaitez répondre à une modification de la valeur d'une propriété, ajoutez un gestionnaire d' OnValueChanged à la propriété.Pour plus d'informations, consultez Propagation et réponse aux modifications en attente.

Exemple

L'exemple suivant met à jour une propriété lorsqu'une relation de domaine est instanciée pour lier deux éléments.La règle sera déclenchée non seulement lorsque l'utilisateur crée un lien sur un diagramme, mais également si le code du programme crée un lien.

Pour tester cet exemple, créer un DÉSOLÉ à l'aide de le modèle de solution de flux de travail, et insérer le code suivant dans un fichier dans le projet DÉSOLÉ.Générez et exécutez la solution, puis ouvrez le fichier d'exemple dans le projet de débogage.dessinez un lien de commentaire entre une zone de commentaire et un élément de flux.Le texte du commentaire change pour rendre compte de l'élément le plus récent que vous l'avez connecté à.

Dans la pratique, vous écrirez généralement un DeleteRule pour chaque 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 aussi

Concepts

Propagation de modifications en dehors du modèle par des gestionnaires d'événements

Définition de l'emplacement et de la taille de la forme par la classe BoundsRules