Question

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();
            }
        }
    }
Was it helpful?

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.

OTHER TIPS

Although not the correct approach (Paul Lalonde answer is the best), here's how you may know, at any given time, if the model is being serialized (= loading):

this.Store.TransactionManager.CurrentTransaction!= null &&
this.Store.TransactionManager.CurrentTransaction.IsSerializing
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top