Enabling your DSL for MEF extensions
One month ago, I described an extension to the DslDesigner to author modelbus. This is a real life example of what could be a MEF extension to our authoring tool. Writing such an extension is easy as shown in the “How to: extend the Domain-Specific Language Designer” page on the MSDN library and in the sample named SimpleDslDesignerExtension in the code gallery download tab for the VsVmSdk
I terminated my article by promising to explain how you could, yourself, enable MEF extensions to your DSL, so that your customers, partners, colleagues or even yourself can write extensions targeting your DSL. This is the object of my post today.
1. Download the zip file containing a few additional .tt files
This file contains a few text templates that really only include text templates provided in the SDK. Those are in subfolders depending on whether you’ll need to add them to the Dsl or to the DslPackage project.
2. Update your DSL
To MEF-extension enable you DSL, as a DSL author will need to:
1/ Add DesignerExtensionMetadataAttribute.tt, GestureExtensionControler.tt, GestureExtensionEnablement.tt (form the zip file) to the DSL project in the Dsl\GeneratedCode folder.
2/ Add CommandExtensionRegistrar.tt, CommandExtensionVSCT.tt, PackageExtensionEnablement.tt, ValidationExtensionEnablement.tt, ValidationExtensionRegistrar.tt (also in the zip file) to the DslPackage project, in the DslPackage\GeneratedCode folder
- you could choose not to authorise validation extensions (in that case, just don’t add the 2 validation .tt files in your DslPackage project). If you do want to enable MEF-validation extensions, of course you need to have activated the validation in your DslDefinition.dsl (in the Dsl explorer, you will have previously changed the properties in Editor|Validation object).
- In CommandExtensionVSCT.tt, there is a Guid that must be kept synchronized with the CommandSetId Guid, by copying the same initialization string as in Constants.tt. This is because this guid is not contained in the DslDefinition.dsl, unfortunately, but is updated when the Dsl is unfolded. This is the same principle as in GeneratedVsct.tt
3/ Add one line to the DslPackage\Commands.vsct to include the newly generated CommandExtensionVSCT.vsct (from CommandExtensionVSCT.tt): <Include href="GeneratedCode\CommandExtensionVSCT.vsct"/>
<?xml version="1.0" encoding="utf-8"?>
<CommandTable xmlns="https://schemas.microsoft.com/VisualStudio/2005-10-18/CommandTable" xmlns:xs="https://www.w3.org/2001/XMLSchema">
<!-- This file contains custom command definitions. –>
<!-- NOTE: Each time commands are added or changed, the "version" parameter to the –>
<!-- ProvideMenuResource attribute in Shell\Package.tt should be incremented. –>
<!-- This causes Visual Studio to re-merge the menu definitions for the package. –>
<!-- Otherwise, changes won't take effect until the next time devenv /setup is run. –>
Transform all templates, and rebuild your DSL. It is now enabled to discover MEF extensions. That’s that simple!
3. Write a test extension.
To write an extension, do something similar to “How to: extend the Domain-Specific Language Designer” , but of course referencing your Dsl and if necessary DslPackage DLLs, using your own namespaces, and your concepts.