How To: Generate Code from Team System UML Diagrams in VS 2010 Team System Beta 2 (Update 4)

UPDATE: You can find an updated description for VS 2010 RTM here

Here is the first code-snippet about how to generate code from UML-Diagrams using T4 Text-Templates. 

image

Here are the steps:

1. Create a model project called ModelingProject1.modelproj

2. Insert Classes with properies at the root level of the model using the diagrams

3. Create a file Generator.tt that contains the text below

4. Save the .tt file to have a code-behind template generated under the .tt file that contains the output.

5. If you want to regenerate press the new button (most right in the toolbar of the solution explorer called “Transform All Templates” or save the template again

6. Optional: To get Syntax Coloring and intelli-sense on the template go to the Extension Manager (Tools Menu->Extension Manager->Online Gallery) and search for a T4 Editor of your choice.

Here is the code for copy paste:

<#@ template language="C#" debug="true" hostSpecific="true" #>
<#@ output extension=".cs"#>
<#@ assembly name="Microsoft.VisualStudio.Uml.Extensions.dll"#>
<#@ assembly name="Microsoft.VisualStudio.Uml.Interfaces.dll"#>
<#@ assembly name="Microsoft.VisualStudio.Uml.Interfaces.dll"#>
<#@ import namespace="Microsoft.VisualStudio.Uml.Classes" #>
<#@ import namespace="Microsoft.VisualStudio.Uml.Extensions" #>
<#   

string projectPath = System.IO.Path.GetDirectoryName(this.Host.TemplateFile)
                    + @"\..\ModelingProject1\ModelingProject1.modelproj";
using (IModelingProject project = ModelingProject.Load(projectPath))
{
   IModelStore store = project.Store;
   foreach (IElement element in store.Root.OwnedElements)
   {
      IClass classElement = element as IClass;
      if (classElement != null) {
        #>

        class <#= classElement.Name #> {
           <# foreach (IFeature theFeat in classElement.Features){#>
              string <#= theFeat.Name #> {get;set;};
           <#}#>
        }
        <#
      }
   }
   project.Close();
}
#>

Note there are also a lot of extenison methods defined for IUML*. Here is a list of tasks you can do with the UML API easier. I did not try it though.

https://msdn.microsoft.com/en-us/library/ee329525(VS.100).aspx

And here is a more complex sample that generates class and properties from the Model.

<#@ template language="C#3.5" debug="true" hostSpecific="true" #>
<#@ Assembly Name="System.Core.dll" #>
<#@ assembly name="Microsoft.VisualStudio.Uml.Extensions.dll"#>
<#@ assembly name="Microsoft.VisualStudio.Uml.Interfaces.dll"#>
<#@ import namespace="System" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="Microsoft.VisualStudio.Uml.Classes" #>
<#@ import namespace="Microsoft.VisualStudio.Uml.Extensions" #>
using System;
<#   
var projectPath = System.IO.Path.GetDirectoryName(this.Host.TemplateFile)+ @"\..\ModelingProject1\ModelingProject1.modelproj";
using (IModelingProject project = ModelingProject.Load(projectPath))
{
   foreach(IClass classElement in project.Store.Root.OwnedElements.OfType<IClass>())
   {
    var baseClass = classElement.SuperClasses.FirstOrDefault();
    var baseClassNamespaceName = (baseClass!=null ) ? baseClass.Namespace.Name+"." : "";
    var baseClassName = (baseClass!=null) ? baseClassNamespaceName+baseClass.Name : "System.Object";
    var properties = classElement.OwnedAttributes.OfType<IProperty>().ToArray();

    #>
public <#= classElement.IsAbstract ? "abstract ":"" #>partial class <#= classElement.Name #>: <#= baseClassName #>
{
<#
    if (properties.Length>0)
    {
     WriteLine("\t\t// properties");
    }
    foreach(IProperty property in properties)
    {
     var propertyName = property.Name;
     var fieldName = "_"+property.Name.Substring(0,1).ToLowerInvariant()+property.Name.Substring(1);
     var propertyTypeName = typeof(System.Object).FullName;
     if (property.Type!=null)
     {
      propertyTypeName = property.Type.Name;
      if (property.Type.Namespace!=null && property.Type.Namespace.Name!=baseClassNamespaceName)
      {
       propertyTypeName = property.Type.Namespace.Name+"."+propertyTypeName;
      }
     }
     //var propertyTypeName = (property.Type!=null) ? property.Type.Name : ;
#>
  #region @ <#= propertyName #>
  private <#= propertyTypeName #> <#= fieldName #>;
  public <#= propertyTypeName #> <#= propertyName #>
  {
   get
   {
    return <#= fieldName #>;
   }
   set
   {
   }
  }
  #endregion
<#
    }
    #>
}

<#
  }
project.Close();
}

#>