You can use preprocess text templates within a UML menu command. Within the code of the text template, or in a separate partial class, you can read the model that is viewed by the diagram.
The approach demonstrated in the following example is suitable for generating text from a single model, when you initiate the operation from one of the model diagrams. To process a model in a separate context, consider using Visual Studio Modelbus to access the model and its elements.
To run this example, create a Visual Studio Extension (VSIX) project. The project name that is used in this example is VdmGenerator. In the source.extension.vsixmanifest file, click Add Content and set the type field to MEF Component and source path referencing the current project. For more information about how to set up this type of project, see How to: Define a Menu Command on a Modeling Diagram.
Add to the project a C# file that contains the following code. This class defines a menu command that will appear on a UML class diagram.
using System;
using System.ComponentModel.Composition;
using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Uml;
using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Presentation;
using Microsoft.VisualStudio.Modeling.ExtensionEnablement;
namespace VdmGenerator
{
[Export(typeof(ICommandExtension))]
[ClassDesignerExtension]
public class GenerateVdmFromClasses : ICommandExtension
{
[Import] public IDiagramContext DiagramContext { get; set; }
public void Execute(IMenuCommand command)
{
// Initialize the template with the Model Store.
VdmGen generator = new VdmGen(
DiagramContext.CurrentDiagram.ModelStore);
// Generate the text and write it.
System.IO.File.WriteAllText
(System.IO.Path.Combine(
Environment.GetFolderPath(
Environment.SpecialFolder.Desktop),
"Generated.txt")
, generator.TransformText());
}
public void QueryStatus(IMenuCommand command)
{
command.Enabled = command.Visible = true;
}
public string Text
{ get { return "Generate VDM"; } }
}
}
The following file is the text template. It generates a line of text for each UML class in the model, and a line for each attribute in each class. Code for reading the model is embedded in the text, delimited by <# ... #>.
To create this file, right-click the project in Solution Explorer, point to Add, and then click New Item. Select Preprocessed Text Template. The file name for this example should be VdmGen.tt. The Custom Tool property of the file should be TextTemplatingFilePreprocessor. For more information about preprocessed text templates, see Run-Time Text Generation by using Preprocessed T4 Text Templates.
<#@ import namespace="Microsoft.VisualStudio.Uml.Classes" #>
<#
foreach (IClass classElement in store.AllInstances<IClass>())
{
#>
Type <#= classElement.Name #> ::
<#
foreach (IProperty attribute in classElement.OwnedAttributes)
{
#>
<#= attribute.Name #> : <#=
attribute.Type == null ? ""
: attribute.Type.Name #>
<#
}
}
#>
The text template generates a C# partial class, which becomes part of your Visual Studio project. In a separate file, add another partial declaration of the same class. This code provides the template with access to the UML model store:
using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Uml;
namespace VdmGenerator
{
public partial class VdmGen
{
private IModelStore store;
public VdmGen(IModelStore s)
{ store = s; }
}
}
To test the project, press F5. A new instance of Visual Studio will start. In this instance, open or create a UML model that contains a class diagram. Add some classes to the diagram, and add some attributes to each class. Right-click in the diagram and then click the example command Generate VDM. The command creates the file C:\Generated.txt. Inspect this file. Its contents should resemble the following text, but it will list your own classes and attributes:
Type Class1 ::
Attribute1 : int
Attribute2 : string
Type Class2 ::
Attribute3 : string