views:

170

answers:

2

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();
            }
        }
    }
+2  A: 

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.

Paul Lalonde
Thank you Paul for your reply. I am going to get some testing done now!
Phill Duffy
It works, very much appreciated. There is a lot to learn in DSL but am finding it is definately worth the effort
Phill Duffy
As a semi-side question. If I wanted to do something simular for when the Diagram is created (Project > Add Item) should I use the constructor then or shall I use the same pattern as here? Thanks
Phill Duffy
A: 

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
Luis Filipe