Condividi tramite


Le regole propagano le modifiche all'interno del modello

È possibile creare una regola di propagare una modifica da un elemento a un altro nell'SDK di visualizzazione e modellazione (VMSDK).Quando viene apportata una modifica a qualsiasi elemento nell'archivio, le regole vengono fornite da eseguire, in genere quando la transazione più esterna viene eseguito il commit.Esistono tipi diversi di regole per i diversi tipi di eventi, ad esempio l'aggiunta di un elemento, o eliminarlo.È possibile collegare le regole a tipi specifici di elementi, di forme, o di diagramma.Numerose funzionalità incorporate sono definite dalle regole: ad esempio, le regole garantisce che un diagramma sia aggiornato quando le modifiche del modello.È possibile personalizzare il linguaggio specifico di dominio aggiungendo le proprie regole.

Le regole di archiviazione sono particolarmente utili per la propagazione delle modifiche nell'archivio, ovvero modifiche agli elementi del modello, relazioni, forme o connettori e le proprietà del dominio.Le regole non vengono eseguiti quando l'utente richiama i controlli di annullamento o ripristino.Invece, il gestore delle transazioni garantisce che il contenuto dell'archivio vengono ripristinati nello stato corretto.Se si desidera propagare le modifiche alle risorse all'esterno dell'archivio, utilizzare gli eventi nell'archivio.Per ulteriori informazioni, vedere I gestori eventi propagano le modifiche al di fuori del modello.

Ad esempio, si supponga di voler specificare che ogni volta che l'utente o il codice viene creato un nuovo elemento di tipo ExampleDomainClass, un elemento aggiuntivo di un altro tipo sia creato in un'altra parte del modello.È possibile scrivere un AddRule e associarlo a ExampleDomainClass.Scrivere il codice della regola creare l'elemento aggiuntivo.

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]

Il codice di una regola deve modificare lo stato di soli elementi nell'archivio; ovvero la regola necessario modificare solo gli elementi del modello, le relazioni, forme, i connettori, diagrammi, o le relative proprietà.Se si desidera propagare le modifiche alle risorse all'esterno dell'archivio, definire gli eventi dell'archivio.Per ulteriori informazioni, vedere I gestori eventi propagano le modifiche al di fuori del modello.

Per definire una regola

  1. Definire una regola come classe con prefisso RuleOn attributo.L'attributo associa la regola con uno delle classi di dominio, le relazioni, o elementi del diagramma.La regola è applicata a ogni istanza della classe, che può essere astratta.

  2. Registrare la regola aggiungerla al set restituito da GetCustomDomainModelTypes() nella classe del modello di dominio.

  3. Derivare la classe di regola da una delle classi astratte della regola e scrivere il codice del metodo di esecuzione.

Nelle sezioni seguenti vengono descritti più dettagliatamente i passaggi seguenti.

Per definire una regola in una classe di dominio

  • In un file di codice personalizzato, definire una classe e premetterla con RuleOnAttribute attributo:

    [RuleOn(typeof(ExampleElement), 
         // Usual value – but required, because it is not the default:
         FireTime = TimeToFire.TopLevelCommit)] 
    class MyRule ...
    
  • Il soggetta tipo nel primo parametro può essere una classe di dominio, una relazione di dominio, una forma, un connettore, o un diagramma.In genere, applicare le regole alle classi di dominio e le relazioni.

    FireTime è in genere TopLevelCommit.Questo assicura che la regola venga eseguito solo dopo tutte le modifiche principali della transazione sia stata eseguita.Le alternative sono inline, che esegue la regola precedenza dopo la modifica, e LocalCommit, che esegue la regola alla fine della transazione corrente (che potrebbe non essere il più esterno).È anche possibile impostare la priorità di una regola influire sul proprio ordine della coda, ma si tratta di un metodo non inaffidabile di ottenere il risultato desiderato.

  • È possibile specificare una classe astratta come tipo tematico.

  • La regola viene applicata a tutte le istanze della classe dell'oggetto.

  • il valore predefinito per FireTime è TimeToFire.TopLevelCommit.Ciò causa la regola essere eseguito quando la transazione più esterna viene eseguito il commit.Un'alternativa consiste TimeToFire.Inline.Ciò causa la regola essere eseguito precedentemente dopo l'evento scatenante.

Per registrare la regola

  • Aggiungere la classe di regola all'elenco dei tipi restituiti da GetCustomDomainModelTypes nel modello di dominio:

    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();
       }
     }
    
  • In caso di dubbi sul nome della classe del modello di dominio, cercare nel file Dsl\GeneratedCode\DomainModel.cs

  • Scrivere il codice in un file di codice personalizzato nel progetto di modello DSL.

Per scrivere il codice della regola

  • Derivare la classe di regola da una delle classi di base:

    Classe base

    Trigger

    AddRule

    Un elemento, un collegamento, o una forma viene aggiunto.

    Utilizzare questa opzione per rilevare nuove relazioni, oltre ai nuovi elementi.

    ChangeRule

    Un valore della proprietà del dominio viene modificato.L'argomento del metodo fornisce i valori nuovi e precedenti.

    Per le forme, questa regola viene attivata quando incorporati AbsoluteBounds modifiche delle proprietà, se la forma viene spostata.

    In molti casi, è preferibile di cui eseguire l'override OnValueChanged o OnValueChanging nel gestore della proprietà.Questi metodi vengono chiamati immediatamente prima di e dopo la modifica.Al contrario, la regola generale viene eseguito alla fine della transazione.Per ulteriori informazioni, vedere Gestori di modifica del valore delle proprietà del dominio.

    NotaNota
    Questa regola non viene attivata quando un collegamento viene creato o eliminato.invece, scrivere AddRule e DeleteRule per la relazione di dominio.

    DeletingRule

    Attivato quando un elemento o un collegamento sta per eliminar.La proprietà ModelElement.IsDeleting è valido fino alla fine della transazione.

    DeleteRule

    Esecuzione di un elemento o un collegamento è stato eliminato.La regola viene eseguita dopo tutte le altre regole è stata eseguita, inclusi DeletingRules.ModelElement.IsDeleting è false e ModelElement.IsDeleted è true.Per consentire un'operazione di annullamento successiva, l'elemento non viene rimosso dalla memoria, ma viene rimosso da Store.ElementDirectory.

    MoveRule

    Un elemento viene spostato da una partizione dell'archivio a un altro.

    Si noti che questo non è correlato alla posizione grafica di una forma.)

    RolePlayerChangeRule

    Questa regola si applica solo alle relazioni di dominio.Viene attivata se in modo esplicito si assegna un elemento del modello a una delle estremità di un collegamento.

    RolePlayerPositionChangeRule

    Attivato quando l'ordine di collegamenti a o da un elemento viene modificato utilizzando i metodi di MoveToIndex o di MoveBefore su un collegamento.

    TransactionBeginningRule

    Esecuzione di una transazione viene creata.

    TransactionCommittingRule

    Eseguito quando la transazione sta per essere eseguito.

    TransactionRollingBackRule

    Eseguito quando la transazione sta per essere ripristinato.

  • Ogni classe dispone di un metodo che esegue l'override di.tipo override nella classe per individuarla.Il parametro di questo metodo consente di identificare l'elemento che si sta modificando.

Tenere presenti le informazioni seguenti sulle regole:

  1. Il set di modifiche in una transazione può attivare molte regole.In genere, le regole vengono eseguite quando la transazione più esterna viene eseguito il commit.Vengono eseguiti in un ordine non specificato.

  2. Una regola viene eseguita sempre in una transazione.Di conseguenza, non è necessario creare una nuova transazione per apportare modifiche.

  3. Le regole non verranno eseguite quando una transazione viene ripristinata, o quando le operazioni di annullamento o ripristino vengono eseguite.Queste operazioni vengono reimpostati tutto il contenuto dell'archivio dello stato precedente.Pertanto, se la regola modifica lo stato di qualsiasi elemento all'esterno dell'archivio, non è possibile mantenere in sincronismo con il contenuto dell'archivio.Per aggiornamento di stato all'esterno dell'archivio, è consigliabile utilizzare gli eventi.Per ulteriori informazioni, vedere I gestori eventi propagano le modifiche al di fuori del modello.

  4. Alcune regole vengono eseguite quando viene caricato un modello dal file.Per determinare se upload o risparmiando è in corso, utilizzare store.TransactionManager.CurrentTransaction.IsSerializing.

  5. Se il codice della regola crea più trigger di regola, verranno aggiunti alla fine dell'elenco di infornamento e saranno eseguiti prima che la transazione completi.DeletedRules viene eseguito dopo tutte le altre regole.Una regola può eseguire più volte in una transazione, una volta per ogni modifica.

  6. Per passare informazioni a e dalle regole, è possibile memorizzare le informazioni in TransactionContext.Si tratta di un dizionario che viene gestito durante una transazione.Viene eliminato quando la transazione termina.Gli argomenti in ogni regola forniscono l'accesso.Tenere presente che le regole non vengono eseguiti in un ordine previsto.

  7. Regole di utilizzo dopo la considerazione le altre alternative.Ad esempio, se si desidera aggiornare una proprietà quando un valore viene modificato, considerare l'utilizzo di una proprietà calcolata.Se si desidera limitare le dimensioni o la posizione di una forma, utilizzare un oggetto BoundsRule.Se si desidera rispondere a una modifica in un valore di proprietà, aggiungere OnValueChanged gestore alla proprietà.Per ulteriori informazioni, vedere Risposta alle modifiche e propagazione delle modifiche.

Esempio

Nell'esempio seguente viene aggiornato una proprietà quando una relazione di dominio viene creata un'istanza per collegare due elementi.La regola viene attivata non solo quando l'utente crea un collegamento su un diagramma, ma anche se il codice del programma crea un collegamento.

Per testare questo esempio, creare un modello DSL utilizzando il modello della soluzione flusso di attività e inserire il codice seguente in un file nel progetto di Dsl.Compilare ed eseguire la soluzione e aprire il file di esempio nel progetto di debug.Creare un collegamento di commento tra una forma commenti e un elemento del flusso.Il testo in commento al rapporto sull'elemento più recente che è stato connesso a.

In pratica, in genere quella di un DeleteRule per ogni 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();
    }
  }

}

Vedere anche

Concetti

I gestori eventi propagano le modifiche al di fuori del modello

Le regole associate (BoundsRules) vincolano posizione e dimensione delle forme