Las reglas propagan los cambios dentro del modeloRules Propagate Changes Within the Model

Puede crear una regla de almacén para propagar un cambio de un elemento a otro en la visualización y modelado de SDK (VMSDK).You can create a store rule to propagate a change from one element to another in Visualization and Modeling SDK (VMSDK). Cuando se produce un cambio a cualquier elemento en el almacén, las reglas se programan para ejecutarse, normalmente cuando se confirma la transacción más externa.When a change occurs to any element in the Store, rules are scheduled to be executed, usually when the outermost transaction is committed. Hay diferentes tipos de reglas para los diferentes tipos de eventos, como agregar un elemento o eliminarlo.There are different types of rules for different kinds of events, such as adding an element, or deleting it. Puede asociar reglas a tipos específicos de elementos, formas o diagramas.You can attach rules to specific types of elements, shapes, or diagrams. Muchas características integradas se definen mediante reglas: por ejemplo, las reglas de asegurarse de que se actualiza un diagrama cuando cambia el modelo.Many built-in features are defined by rules: for example, rules ensure that a diagram is updated when the model changes. Puede personalizar su lenguaje específico de dominio mediante la adición de sus propias reglas.You can customize your domain-specific language by adding your own rules.

Almacén de reglas son especialmente útiles para propagar los cambios en el almacén: es decir, los cambios en los elementos del modelo, las relaciones, formas o conectores y su dominio propiedades.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. Las reglas no se ejecutan cuando el usuario invoca los comandos Deshacer o rehacer.Rules do not run when the user invokes the Undo or Redo commands. En su lugar, el Administrador de transacciones garantiza que el contenido del almacén se restaura en el estado correcto.Instead, the transaction manager makes sure that the store contents are restored to the correct state. Si desea propagar los cambios a los recursos fuera de la tienda, use almacenar eventos.If you want to propagate changes to resources outside the store, use Store Events. Para obtener más información, consulte controladores propagar cambios fuera el modelo de evento.For more information, see Event Handlers Propagate Changes Outside the Model.

Por ejemplo, suponga que desea especificar que cada vez que el usuario (o el código) crea un nuevo elemento de tipo ExampleDomainClass, se crea un elemento adicional de otro tipo en otra parte del modelo.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. Puede escribir un AddRule y asócielo con ExampleDomainClass.You could write an AddRule and associate it with ExampleDomainClass. Se escribirá código en la regla para crear el elemento adicional.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();
   }
 }
}

Nota

El código de una regla debe cambiar el estado únicamente de los elementos dentro del almacén; es decir, debe cambiar la regla solo elementos del modelo, las relaciones, formas, conectores, diagramas o sus propiedades.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 desea propagar los cambios a los recursos fuera de la tienda, defina almacenar eventos.If you want to propagate changes to resources outside the store, define Store Events. Para obtener más información, vea controladores propagar cambios fuera el modelo de eventoFor more information, see Event Handlers Propagate Changes Outside the Model

Para definir una reglaTo define a rule

  1. Defina la regla como una clase con el prefijo del RuleOn atributo.Define the rule as a class prefixed with the RuleOn attribute. El atributo asocia la regla a una de sus clases de dominio, relaciones o elementos del diagrama.The attribute associates the rule with one of your domain classes, relationships, or diagram elements. La regla se aplicará a todas las instancias de esta clase, que puede ser abstracta.The rule will be applied to every instance of this class, which may be abstract.

  2. Registrar la regla, éste se agrega al conjunto devuelto por GetCustomDomainModelTypes() en la clase de modelo de dominio.Register the rule by adding it to the set returned by GetCustomDomainModelTypes() in your domain model class.

  3. Derive la clase de regla de una de las clases abstractas de la regla y escribir el código del método de ejecución.Derive the rule class from one of the abstract Rule classes, and write the code of the execution method.

    Las siguientes secciones describen estos pasos con más detalle.The following sections describe these steps in more detail.

Para definir una regla en una clase de dominioTo define a rule on a domain class

  • En un archivo de código personalizado, defina una clase y un prefijo con el RuleOnAttribute atributo: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 ...
    
  • El tipo de sujeto en el primer parámetro puede ser una clase de dominio, relación de dominio, forma, conector o diagrama.The subject type in the first parameter can be a domain class, domain relationship, shape, connector, or diagram. Por lo general, aplicar reglas a las relaciones y las clases de dominio.Usually, you apply rules to domain classes and relationships.

    El FireTime suele ser TopLevelCommit.The FireTime is usually TopLevelCommit. Esto garantiza que la regla se ejecuta sólo una vez realizados todos los cambios principales de la transacción.This ensures that the rule is executed only after all the primary changes of the transaction have been made. Las alternativas sean Inline, que se ejecuta la regla muy poco tiempo después del cambio; y LocalCommit, que ejecuta la regla al final de la transacción actual (que no sea la más externa).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). También puede establecer la prioridad de una regla que afecta a su orden en la cola, pero se trata de un método no confiable de lograr el resultado que necesita.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.

  • Puede especificar una clase abstracta como el tipo de sujeto.You can specify an abstract class as the subject type.

  • La regla se aplica a todas las instancias de la clase de asunto.The rule applies to all instances of the subject class.

  • El valor predeterminado de FireTime es TimeToFire.TopLevelCommit.The default value for FireTime is TimeToFire.TopLevelCommit. Esto hace que la regla que se ejecuta cuando se confirma la transacción más externa.This causes the rule to be executed when the outermost transaction is committed. Una alternativa es TimeToFire.Inline.An alternative is TimeToFire.Inline. Esto hace que la regla que se ejecute poco después del evento desencadenador.This causes the rule to be executed soon after the triggering event.

Para registrar la reglaTo register the rule

  • Agregue la clase de regla a la lista de tipos devuelta por GetCustomDomainModelTypes en el modelo de dominio: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 no está seguro del nombre de la clase de modelo de dominio, busque en el archivo Dsl\GeneratedCode\DomainModel.csIf you are not sure of the name of your domain model class, look inside the file Dsl\GeneratedCode\DomainModel.cs

  • Este código se puede escribir en un archivo de código personalizado en el proyecto DSL.Write this code in a custom code file in your DSL project.

Para escribir el código de la reglaTo write the code of the rule

  • Derive la clase de regla de una de las clases base siguientes:Derive the rule class from one of the following base classes:

    Clase baseBase class DesencadenadorTrigger
    AddRule Se agrega un elemento, un vínculo o una forma.An element, link, or shape is added.

    Utilícelo para detectar nuevas relaciones, además de nuevos elementos.Use this to detect new relationships, in addition to new elements.
    ChangeRule Se cambia un valor de propiedad de dominio.A domain property value is changed. El argumento de método proporciona los valores antiguos y nuevos.The method argument provides the old and new values.

    Las formas, esta regla se desencadena cuando la integrada AbsoluteBounds cambios de propiedades, si se mueve la forma.For shapes, this rule is triggered when the built-in AbsoluteBounds property changes, if the shape is moved.

    En muchos casos, es más cómodo invalidar OnValueChanged o OnValueChanging en el controlador de propiedad.In many cases, it is more convenient to override OnValueChanged or OnValueChanging in the property handler. Estos métodos se invocan inmediatamente antes y después del cambio.These methods are called immediately before and after the change. Por el contrario, la regla se ejecuta normalmente al final de la transacción.By contrast, the rule usually runs at the end of the transaction. Para obtener más información, consulte controladores de cambio de valor de propiedad de dominio.For more information, see Domain Property Value Change Handlers. Nota: esta regla no se desencadena cuando se crea o se elimina un vínculo.Note: This rule is not triggered when a link is created or deleted. En su lugar, escribir una AddRule y un DeleteRule para la relación de dominio.Instead, write an AddRule and a DeleteRule for the domain relationship.
    DeletingRule Se desencadena cuando un elemento o vínculo se va a eliminar.Triggered when an element or link is about to be deleted. La propiedad ModelElement.IsDeleting es true hasta el final de la transacción.The property ModelElement.IsDeleting is true until the end of the transaction.
    DeleteRule Se realiza cuando se ha eliminado un elemento o vínculo.Performed when an element or link has been deleted. La regla se ejecuta después de que se han ejecutado todas las demás reglas, incluidos los DeletingRules.The rule is executed after all other rules have been executed, including DeletingRules. ModelElement.IsDeleting es false y ModelElement.IsDeleted es true.ModelElement.IsDeleting is false, and ModelElement.IsDeleted is true. Para permitir una acción de deshacer posterior, el elemento no quita en realidad de la memoria, pero se quita del 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 elemento se mueve desde un almacén de partición a otra.An element is moved from one store partition to another.

    (Tenga en cuenta que esto no está relacionado con la posición de una forma gráfica.)(Notice that this is not related to the graphical position of a shape.)
    RolePlayerChangeRule Esta regla solo se aplica a las relaciones de dominio.This rule applies only to domain relationships. Se desencadena si asigna explícitamente un elemento del modelo a cualquiera de los extremos de un vínculo.It is triggered if you explicitly assign a model element to either end of a link.
    RolePlayerPositionChangeRule Se desencadena cuando el orden de los vínculos a o desde un elemento se cambia utilizando los métodos MoveBefore o MoveToIndex en un vínculo.Triggered when the ordering of links to or from an element is changed using the MoveBefore or MoveToIndex methods on a link.
    TransactionBeginningRule Se ejecuta cuando se crea una transacción.Executed when a transaction is created.
    TransactionCommittingRule Se ejecuta cuando la transacción está a punto de confirmarse.Executed when the transaction is about to be committed.
    TransactionRollingBackRule Se ejecuta cuando la transacción está a punto de revertirse.Executed when the transaction is about to be rolled back.
  • Cada clase tiene un método que reemplazar.Each class has a method that you override. Tipo override en su clase para detectarlo.Type override in your class to discover it. El parámetro de este método identifica el elemento que se va a cambiar.The parameter of this method identifies the element that is being changed.

    Tenga en cuenta los siguientes puntos acerca de las reglas:Notice the following points about rules:

  1. El conjunto de cambios en una transacción, puede desencadenar muchas reglas.The set of changes in a transaction might trigger many rules. Por lo general, las reglas se ejecutan cuando se confirma la transacción más externa.Usually, the rules are executed when the outermost transaction is committed. Se ejecutan en un orden no especificado.They are executed in an unspecified order.

  2. Una regla siempre se ejecuta dentro de una transacción.A rule is always executed inside a transaction. Por lo tanto, no es necesario crear una nueva transacción para realizar cambios.Therefore, you do not have to create a new transaction to make changes.

  3. Las reglas no se ejecutan cuando se revierte una transacción, o cuando se realizan las operaciones de deshacer o rehacer.Rules are not executed when a transaction is rolled back, or when the Undo or Redo operations are performed. Estas operaciones restablecen todo el contenido de la tienda a su estado anterior.These operations reset all the content of the Store to its previous state. Por lo tanto, si la regla cambia el estado de cualquier elemento fuera de la tienda, podría no tenga synchronism con el almacén de contenido.Therefore, if your rule changes the state of anything outside the Store, it might not keep in synchronism with the Store content. Para actualizar el estado fuera de la tienda, es mejor utilizar eventos.To update state outside the Store, it is better to use Events. Para obtener más información, consulte controladores propagar cambios fuera el modelo de evento.For more information, see Event Handlers Propagate Changes Outside the Model.

  4. Algunas de las reglas se ejecutan cuando un modelo se carga desde el archivo.Some rules are executed when a model is loaded from file. Para determinar si cargar o guardar está en curso, utilice store.TransactionManager.CurrentTransaction.IsSerializing.To determine whether loading or saving is in progress, use store.TransactionManager.CurrentTransaction.IsSerializing.

  5. Si el código de la regla crea varios desencadenadores de regla, se agregarán al final de la lista de activación y se ejecutará antes de que finalice la transacción.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 se ejecutan después de todas las demás reglas.DeletedRules are executed after all other rules. Una regla puede ejecutar muchas veces en una transacción, una vez por cada cambio.One rule can run many times in a transaction, one time for each change.

  6. Para pasar información desde y hacia las reglas, puede almacenar la información de la TransactionContext.To pass information to and from rules, you can store information in the TransactionContext. Esto es simplemente un diccionario que se mantiene durante la transacción.This is just a dictionary that is maintained during the transaction. Se eliminan cuando finaliza la transacción.It is disposed when the transaction ends. Los argumentos de evento en cada regla proporcionan acceso a él.The event arguments in each rule provide access to it. Recuerde que las reglas no se ejecutan en un orden predecible.Remember that rules are not executed in a predictable order.

  7. Usar reglas tras considerar otras alternativas.Use rules after considering other alternatives. Por ejemplo, si desea actualizar una propiedad cuando cambia un valor, considere la posibilidad de usar una propiedad calculada.For example, if you want to update a property when a value changes, consider using a calculated property. Si desea restringir el tamaño o la ubicación de una forma, use un BoundsRule.If you want to constrain the size or location of a shape, use a BoundsRule. Si desea responder a un cambio en un valor de propiedad, agregue un OnValueChanged controlador a la propiedad.If you want to respond to a change in a property value, add an OnValueChanged handler to the property. Para obtener más información, consulte responder a y propagar los cambios.For more information, see Responding to and Propagating Changes.

EjemploExample

En el ejemplo siguiente se actualiza una propiedad cuando se crea una instancia de una relación de dominio para vincular dos elementos.The following example updates a property when a domain relationship is instantiated to link two elements. No solo cuando el usuario crea un vínculo en un diagrama, sino también si el código de programa crea un vínculo, se desencadenará la regla.The rule will be triggered not only when the user creates a link on a diagram, but also if program code creates a link.

Para probar este ejemplo, cree un DSL mediante la plantilla de solución de flujo de tareas y, inserte el siguiente código en un archivo en el proyecto de 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. Compilar y ejecutar la solución y abra el archivo de ejemplo en el proyecto de depuración.Build and run the solution, and open the Sample file in the Debugging project. Cree un vínculo de comentarios entre una forma de comentario y un elemento de flujo.Draw a Comment Link between a Comment shape and a flow element. Modificar el texto en el comentario al informe en el elemento más reciente que se ha conectado a.The text in the comment changes to report on the most recent element that you have connected it to.

En la práctica, normalmente se escribiría un DeleteRule para cada 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();
    }
  }

}

Vea tambiénSee Also