Search code examples
c#dsldsl-toolsvisual-studio-2010

DSL Custom Constructor - only calling when created not loading


Info: VS2010, DSL Toolkit, C#

I have a custom constructor on one of my domain classes which adds some child elements. I have an issue as I only want this to run when the domain class element is created , not every time the diagram is opened (which calls the construtors)

        public Entity(Partition partition, params PropertyAssignment[] propertyAssignments)
        : base(partition, propertyAssignments)
    {
        if (SOMETHING_TO_STOP_IT_RUNNING_EACH_TIME)
        {
            using (Transaction tx = Store.TransactionManager.BeginTransaction("Add Property"))
            {
                Property property = new Property(partition);
                property.Name = "Class";
                property.Type = "System.String";
                this.Properties.Add(property);
                this.Version = "1.0.0.0"; // TODO: Implement Correctly
                tx.Commit();
            }
        }
    }

Solution

  • It looks like you are initializing some domain class properties from within the constructor. This is best done by creating an AddRule. AddRules are invoked when an instance of the domain class to which they are attached is added to the model. For example :

    [RuleOn(typeof(Entity), FireTime = TimeToFire.TopLevelCommit)]
    internal sealed partial class EntityAddRule : AddRule
    {
      public override void ElementAdded(ElementAddedEventArgs e)
      {
        if (e.ModelElement.Store.InUndoRedoOrRollback)
          return;
    
        if (e.ModelElement.Store.TransactionManager.CurrentTransaction.IsSerializing)
          return;
    
        var entity = e.ModelElement as Entity;
    
        if (entity == null)
          return;
    
        // InitializeProperties contains the code that used to be in the constructor
        entity.InitializeProperties();
      }
    }
    

    The AddRule then needs to be registered by overriding a function in your domain model class:

    public partial class XXXDomainModel
    {
      protected override Type[] GetCustomDomainModelTypes()
      {
        return new Type[] {
          typeof(EntityAddRule),
        }
      }
    }
    

    For more information about rules, have a look at the "How to: Create Custom Rules" topic in the VS SDK documentation.

    Note: the solution is based on the VS 2008 DSL Tools. YMMV.