It's been a while since my last post, and for good reason. The whole team has had their heads down and has been working very hard towards the completion of an internal milestone. Now I get the chance to take a brief breather and tell the world about what we've been so busy doing. I can't tell you how proud I am of the work we've done. Here's a quick list:
- Ship DSL Tools within VSSDK Feb CTP. - Release first draft of DSL Tools documentation. - Add support for 'port' shapes- A new and vastly improved model (and associated xml format) for the definition of all aspects of a DSL (domain model, shapes, mappings, etc), and some of the code-generation from this model. - Clean, domain-specific, and customizable serialization of models. - And last but not least, vast improvements to the Modeling API.
I was most directly involved in the work on the Modeling API and code-generation work, and I'm excited to share the details. This post will be the first in a series that will cover these areas (and possibly other areas). Given the breadth of customizations that will be allowed by the upcoming DSL Designer (a designer for the DSL definition), it may not be common to have to use the modeling API. Nevertheless, for advanced customizations, and for understanding what the generated code does, it will be necessary to understand the modeling API.
Now where shall I start?
First of all, there are a bunch of naming changes to make things flow better. Here are a few of the biggest ones. I'll add to the list in future postings:
"MetaX" --> "DomainX" (Eg, MetaClass becomes DomainClass)."SubStore" or "MetaModel" --> "DomainModel""XAttribute" --> "XProperty" (Eg, MetaAttribute becomes DomainProperty).
I'll be using the new names from now on.
In this post, I'll assume that you have a domain model defined using the new format, and the code for it generated using the new generators (I'll cover these in a later post). Let's look at how to create the Model Store, and create a couple of domain-classes and relationships?:
To create a store, use one of the following 2 constructors:
public Store(params Type[] domainModelTypes)public Store(IServiceProvider serviceProvider, params Type[] domainModelTypes)
For the domainModelTypes parameter, provide a list of the of your 'DomainModels' (the classes in the generated code that used to be derived from Microsoft.VisualStudio.Modeling.SubStore, but are now derived from Microsoft.VisualStudio.Modeling.DomainModel). The serviceProvider is used by the Store's implementation of IServiceProvider.
For example,
Store store = new Store();
Multiple domain models can be loaded into the store at once. In the example below, a base domain model and an extended domain model are loaded. When there are dependencies between domain models (as in the example below), the domain models should be specified in dependency-order.
Store store = new Store(typeof(BaseActivityDomainModel), typeof(ExtendedActivityDomainModel));
Domain models can also be loaded into the store after construction. For example,
Store store = new Store();store.LoadDomainModels(typeof(ActivityDomainModel));
Make sure you call store.Dispose() once you are done with it.
Let's say you have a domain class called 'Person' and another one called 'Activity' and a domain relationship called 'PersonPerformsActivities' (a relationship from one person to many activities) in your domain model. How would you go about creating instances of these classes and relationships?
Simple, you just use 'new':
// Now to create the link between person and activity, we have a few ways of doing itperson.Activities.Add(activity);// oractivity.Person = person;// orPersonPerformsActivities relationship = new PersonPerformsActivities(person, activity);// There are a few more varieties of the constructor for more complex cases, but these// are the simplest and most common ways to create a link
Seems obvious, but you could not do this with the old Modeling API. Using new() would not work. Instead you had to call Activity.CreateActivity(..) or store.ElementDirectory.CreateElement(typeof(Activity)). We still support the reflective mechanism of creating elements (I'll cover that in a different post), but 90% of cases will probably use new(). I think this is a great improvement in the API and I hope you agree.
I'll stop for now. There is so much to cover, but I'll leave the rest for future posts. As always, comments and feedback are welcome and appreciated.
Thanks,-George