Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Vous pouvez créer une règle de stockage pour propager une modification d’un élément à un autre dans le Visualisation et Modélisation SDK (VMSDK). Lorsqu’une modification se produit sur un élément du Windows Store, les règles sont planifiées pour être exécutées, généralement lorsque la transaction la plus externe est validée. Il existe différents types de règles pour différents types d’événements, tels que l’ajout d’un élément ou sa suppression. Vous pouvez attacher des règles à des types spécifiques d’éléments, de formes ou de diagrammes. De nombreuses fonctionnalités intégrées sont définies par des 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 de magasin sont particulièrement utiles pour propager les modifications à l’intérieur du magasin, c’est-à-dire les modifications apportées aux éléments de modèle, aux relations, aux formes ou aux connecteurs et à leurs propriétés de domaine. Les règles ne s’exécutent pas lorsque l’utilisateur appelle les commandes Annuler ou Rétablir. Au lieu de cela, le gestionnaire de transactions s’assure que le contenu du magasin est restauré à l’état correct. Si vous souhaitez propager des modifications aux ressources en dehors du magasin, utilisez les événements du magasin. Pour plus d’informations, consultez Les gestionnaires d’événements propagent les modifications en dehors du modèle.
Par exemple, supposons que vous souhaitez spécifier que chaque 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éé dans une autre partie du modèle. Vous pouvez écrire un AddRule et l’associer à ExampleDomainClass. Vous écrivez du code dans la règle pour 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();
}
}
}
Note
Le code d’une règle doit modifier l’état uniquement des éléments à l’intérieur du Windows Store ; autrement dit, la règle doit modifier uniquement les éléments de modèle, les relations, les formes, les connecteurs, les diagrammes ou leurs propriétés. Si vous souhaitez propager des modifications aux ressources en dehors du magasin, définissez les événements de magasin. Pour plus d’informations, consultez Les gestionnaires d’événements propagent les modifications en dehors du modèle.
Pour définir une règle
Définissez la règle en tant que classe précédée de l’attribut
RuleOn. L’attribut associe la règle à l’une de vos classes de domaine, relations ou éléments de diagramme. La règle est appliquée à chaque instance de cette classe, qui peut être abstraite.Enregistrez la règle en l’ajoutant dans l'ensemble retourné par
GetCustomDomainModelTypes()dans votre classe de modèle de domaine.Dérivez la classe de règle de l’une des classes de règle abstraites et écrivez le code de la méthode d’exécution.
Les sections suivantes décrivent ces étapes plus 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 RuleOnAttribute :
[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, une relation de domaine, une forme, un connecteur ou un diagramme. En règle générale, vous appliquez des règles aux classes de domaine et aux relations.
Généralement,
FireTimeestTopLevelCommit. Cela garantit que la règle est exécutée uniquement après que toutes les modifications principales de la transaction ont été apportées. Les alternatives 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 actuelle (qui peut ne pas être la plus externe). Vous pouvez également définir la priorité d’une règle pour affecter son classement dans la file d’attente, mais il s’agit d’une méthode peu fiable d’atteindre le résultat dont vous avez besoin.Vous pouvez spécifier une classe abstraite comme type d’objet.
La règle s’applique à toutes les instances de la classe d’objet.
La valeur
FireTimepar défaut est TimeToFire.TopLevelCommit. Cela entraîne l’exécution de la règle lorsque la transaction la plus externe est validée. Une alternative est TimeToFire.Inline. Cela entraîne l’exécution de la règle 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
GetCustomDomainModelTypesdans 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 n’êtes pas sûr du nom de votre classe de modèle de domaine, examinez le fichier Dsl\GeneratedCode\DomainModel.cs
Écrivez ce code dans un fichier de code personnalisé dans votre projet DSL.
Pour écrire le code de la règle
Dérivez la classe de règle de l’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 des nouveaux éléments.ChangeRule Une valeur de propriété de domaine est modifiée. L’argument de méthode fournit les anciennes et nouvelles valeurs.
Pour les formes, cette règle est déclenchée lorsque la propriété intégréeAbsoluteBoundschange, si la forme est déplacée.
Dans de nombreux cas, il est plus pratique de remplacerOnValueChangedouOnValueChangingdans le gestionnaire de propriétés. Ces méthodes sont appelées immédiatement avant et après la modification. En revanche, la règle s’exécute généralement à la fin de la transaction. Pour plus d’informations, consultez Gestionnaires de modification de valeur de propriété de domaine. Note: Cette règle n’est pas déclenchée lorsqu’un lien est créé ou supprimé. Au lieu de cela, écrivez unAddRuleet unDeleteRulepour 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 a la valeur true 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 une fois que toutes les autres règles ont été exécutées, y compris DeletingRules. ModelElement.IsDeleting a la valeur false et ModelElement.IsDeleted a la valeur true. Pour autoriser une annulation ultérieure, l’élément n’est pas réellement supprimé de la mémoire, mais il est supprimé de Store.ElementDirectory. MoveRule Un élément est déplacé d’une partition de magasin à une 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. Elle est déclenchée si vous affectez explicitement un élément de modèle à l’une des extrémités d’un lien. 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. TransactionBeginningRule Exécuté lors de la création d’une transaction. TransactionCommittingRule Exécuté lorsque la transaction est sur le point d’être validée. TransactionRollingBackRule Exécuté lorsque la transaction est sur le point d'être annulée. Chaque classe a une méthode que vous remplacez. Tapez
overridedans votre classe pour la découvrir. Le paramètre de cette méthode identifie l’élément en cours de modification.Notez les points suivants concernant les règles :
L’ensemble des modifications apportées à une transaction peut déclencher de nombreuses règles. En règle générale, les règles sont exécutées lorsque la transaction la plus externe est validée. Ils sont exécutés dans un ordre non spécifié.
Une règle est toujours exécutée à l’intérieur d’une transaction. Par conséquent, vous n’avez pas besoin de créer une transaction pour apporter des modifications.
Les règles ne sont pas exécutées lorsqu’une transaction est restaurée ou lorsque les opérations Annuler ou Rétablir sont effectuées. Ces opérations réinitialisent tout le contenu du Windows Store à son état précédent. Par conséquent, si votre règle modifie l’état de tout élément en dehors du Windows Store, il se peut qu’elle ne conserve pas le synchronisme avec le contenu du Windows Store. Pour mettre à jour l’état en dehors du Windows Store, il est préférable d’utiliser des événements. Pour plus d’informations, consultez Les gestionnaires d’événements propagent les modifications en dehors du modèle.
Certaines règles sont exécutées lorsqu’un modèle est chargé à partir d’un fichier. Pour déterminer si le chargement ou l’enregistrement est en cours, utilisez
store.TransactionManager.CurrentTransaction.IsSerializing.Si le code de votre règle crée davantage de déclencheurs de règle, ils seront ajoutés à la fin de la liste de déclenchements et seront exécutés avant la fin de la transaction. Les règles supprimées sont exécutées après toutes les autres règles. Une règle peut s’exécuter plusieurs fois dans une transaction, une fois pour chaque modification.
Pour transmettre des informations à et depuis des règles, vous pouvez stocker des informations dans le
TransactionContext. Il s’agit simplement d’un dictionnaire qui est conservé pendant la transaction. Elle est supprimée lorsque la transaction se termine. Les arguments d’événement de chaque règle lui permettent d’y accéder. N’oubliez pas que les règles ne sont pas exécutées dans un ordre prévisible.Utilisez des règles après avoir envisagé d’autres alternatives. 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 limiter la taille ou l’emplacement d’une forme, utilisez un
BoundsRule. Si vous souhaitez répondre à une modification dans une valeur de propriété, ajoutez unOnValueChangedgestionnaire à la propriété. Pour plus d’informations, consultez Réponse aux modifications et propagation des modifications.
Example
L’exemple suivant met à jour une propriété lorsqu’une relation de domaine est instanciée pour lier deux éléments. La règle est 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éez un DSL à l’aide du modèle de solution De flux de tâches et insérez le code suivant dans un fichier dans le projet Dsl. Générez et exécutez la solution, puis ouvrez le fichier Sample dans le projet de débogage. Dessinez un lien de commentaire entre une forme de commentaire et un élément de flux. Le texte du commentaire change pour signaler l’élément le plus récent auquel vous l’avez connecté.
Dans la pratique, vous écrivez 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();
}
}
}