Ampliar DSL mediante MEF
Puede exntend el lenguaje específico (DSL) utilizando managed extensibility framework. (MEF)Usted u otros desarrolladores podrá escribir extensiones para ADSL sin cambiar la definición y el código de programa ADSL.Tales extensiones incluyen comandos de menú, los controladores de arrastrar y colocar, y validación.Los usuarios podrán instalar DSL y, a continuación instalar opcionalmente las extensiones para él.
Además, cuando se habilita MEF en DSL, puede ser más fácil escribir algunas de las características ADSL, aunque todos se compilan así como ADSL.
Para obtener más información sobre MEF, vea Managed Extensibility Framework (MEF).
Para habilitar ADSL que se extenderá por MEF
Cree una nueva carpeta denominada MefExtension dentro del proyecto de DslPackage .Agregue los siguientes archivos a él:
Nombre de archivo
Contenido del archivo
CommandExtensionVSCT.tt
ImportanteEstablezca el GUID en este archivo es igual que el GUID CommandSetId que se definen en DslPackage \GeneratedCode\Constants .tt<#@ Dsl processor="DslDirectiveProcessor" requires="fileName='..\..\Dsl\DslDefinition.dsl'" #> <# // CmdSet Guid must be defined before master template is included // This Guid must be kept synchronized with the CommandSetId Guid in Constants.tt Guid guidCmdSet = new Guid ("00000000-0000-0000-0000-000000000000"); string menuidCommandsExtensionBaseId="0x4000"; #> <#@ include file="DslPackage\CommandExtensionVSCT.tt" #>
CommandExtensionRegistrar.tt
<#@ Dsl processor="DslDirectiveProcessor" requires="fileName='..\..\Dsl\DslDefinition.dsl'" #> <#@ include file="DslPackage\CommandExtensionRegistrar.tt" #>
ValidationExtensionEnablement.tt
<#@ Dsl processor="DslDirectiveProcessor" requires="fileName='..\..\Dsl\DslDefinition.dsl'" #> <#@ include file="DslPackage\ValidationExtensionEnablement.tt" #>
ValidationExtensionRegistrar.tt
Si agrega este archivo, debe habilitar la validación de DSL con al menos uno de los modificadores en editor \Validation en el Explorador de ADSL.
<#@ Dsl processor="DslDirectiveProcessor" requires="fileName='..\..\Dsl\DslDefinition.dsl'" #> <#@ include file="DslPackage\ValidationExtensionRegistrar.tt" #>
PackageExtensionEnablement.tt
<#@ Dsl processor="DslDirectiveProcessor" requires="fileName='..\..\Dsl\DslDefinition.dsl'" #> <#@ include file="DslPackage\PackageExtensionEnablement.tt" #>
Cree una nueva carpeta denominada MefExtension dentro del proyecto de Dsl .Agregue los siguientes archivos a él:
Nombre de archivo
Content
DesignerExtensionMetaDataAttribute.tt
<#@ Dsl processor="DslDirectiveProcessor" requires="fileName='..\..\Dsl\DslDefinition.dsl'" #> <#@ include file="Dsl\DesignerExtensionMetadataAttribute.tt" #>
GestureExtensionEnablement.tt
<#@ Dsl processor="DslDirectiveProcessor" requires="fileName='..\..\Dsl\DslDefinition.dsl'" #> <#@ include file="Dsl\GestureExtensionEnablement.tt" #>
GestureExtensionController.tt
<#@ Dsl processor="DslDirectiveProcessor" requires="fileName='..\..\Dsl\DslDefinition.dsl'" #> <#@ include file="Dsl\GestureExtensionController.tt" #>
Agregue la línea siguiente al archivo existente que se denomina DslPackage\Commands.vsct:
<Include href="MefExtension\CommandExtensionVSCT.vsct"/>
inserte la línea después de la directiva existente de <Include> .
DslDefinition.dsl abierto.
En el Explorador ADSL, seleccione editor \Validation.
En la ventana Propiedades, asegúrese de que al menos una de las propiedades con nombre utiliza… es true.
En la barra de herramientas del explorador de soluciones, haga clic en Transformar todas las plantillas.
Los archivos secundarios aparecen bajo cada uno de los archivos que agregó.
Compile y ejecute la solución para comprobar que sigue funcionando.
DSL ahora MEF-se habilitada.Puede escribir comandos de menú, los gestos los controladores, y las restricciones de validación como extensiones MEF.Puede escribir estas extensiones en la solución ADSL así como el código personalizado.Además, usted u otros desarrolladores pueden escribir extensiones independientes de Visual Studio que extienden ADSL.
Crear una extensión para ADSL MEF-habilitado
Si tiene acceso a ADSL MEF-habilitado creado por ti mismo o algún otro, puede escribir extensiones para él.Las extensiones se pueden utilizar para agregar comandos de menú, gestos los controladores, o restricciones de validación.Para crear estas extensiones, se utiliza una solución de extensión de Visual Studio (VSIX).La solución tiene dos partes: un proyecto de biblioteca de clases que compila el ensamblado de código, y un proyecto VSIX esos paquetes el ensamblado.
Para crear una extensión VSIX ADSL
Cree un nuevo proyecto de biblioteca de clases.Para ello, en el cuadro de diálogo de Nuevo proyecto , Visual Basic seleccione o Visual c# y Biblioteca de clasesseleccione.
En el nuevo proyecto de biblioteca de clases, agregue una referencia al ensamblado ADSL.
Este ensamblado tiene normalmente un nombre que finaliza con “. Dsl.dll”.
Si tiene acceso al proyecto ADSL, puede encontrar el archivo de ensamblado en el directorio Dsl\bin\*
Si tiene acceso al archivo ADSL VSIX, puede encontrar el ensamblado cambiando la extensión de nombre del archivo VSIX en “.zip”.Descomprima el archivo .zip.
Agregue referencias a los siguientes ensamblados de .NET:
Microsoft.VisualStudio.Modeling.Sdk.11.0.dll
Microsoft.VisualStudio.Modeling.Sdk.Diagrams.11.0.dll
Microsoft.VisualStudio.Modeling.Sdk.Shell.11.0.dll
System.ComponentModel.Composition.dll
System.Windows.Forms.dll
Cree un proyecto VSIX en la misma solución.Para ello, en el cuadro de diálogo de Nuevo proyecto , expanda Visual Basic o Visual c#, haga clic en Extensibilidady, a continuación proyecto de VSIX.
En el explorador de soluciones, haga clic con el botón secundario en el proyecto VSIX y haga clic en Establecer como proyecto de inicio.
En el nuevo proyecto, abra source.extension.vsixmanifest.
Haga clic en Agregar contenido.En el cuadro de diálogo, establezca Tipo de contenido a Componente MEF, y proyecto de origen al proyecto de biblioteca de clases.
Agregue una referencia de VSIX a ADSL.
En source.extension.vsixmanifest, haga clic en Agregar referencia
En el cuadro de diálogo, haga clic agregue la carga y a continuación el archivo VSIX ADSL.El archivo VSIX es integrado la solución ADSL, en DslPackage\bin\*.
Esto permite a los usuarios instalar ADSL y la extensión al mismo tiempo.Si el usuario ha instalado DSL, solo la extensión se instalará.
Revise y actualice los demás campos de source.extension.vsixmanifest.Haga clic en Ediciones seleccionar y compruebe que las versiones correctas de Visual Studio se establecen.
Agregue código al proyecto de biblioteca de clases.utilice los ejemplos en la sección siguiente como guía.
Puede agregar cualquier número de comando, de gestos, y clases de validación.
para probar la extensión, presione F5.En la instancia experimental de Visual Studio, cree o abra un archivo de ejemplo ADSL.
Extensiones MEF de escritura para el dominio (ADSL)
Puede escribir extensiones en el proyecto de código de ensamblado de una solución independiente de extensión ADSL.También puede utilizar MEF en el proyecto de DslPackage, como medio cómodo a los comandos de escritura, a los gestos, y el código de validación como parte del ADSL.
Comandos de menú
Para escribir un comando de menú, defina una clase que implemente ICommandExtension y prefijo la clase con el atributo definido en DSL, denominado TheDslCommandExtension.Puede escribir más de una clase de comando de menú.
se llamaQueryStatus() siempre que el usuario haga clic con el botón secundario en el diagrama.Debe inspeccionar la selección y el conjunto actual command.Enabled para indicar cuando el comando es aplicable.
using System.ComponentModel.Composition;
using System.Linq;
using Company.MyDsl; // My DSL
using Company.MyDsl.ExtensionEnablement; // My DSL
using Microsoft.VisualStudio.Modeling; // Transactions
using Microsoft.VisualStudio.Modeling.Diagrams.ExtensionEnablement; // IVsSelectionContext
using Microsoft.VisualStudio.Modeling.ExtensionEnablement; // ICommandExtension
namespace MyMefExtension
{
// Defined in Dsl\MefExtension\DesignerExtensionMetaDataAttribute.cs:
[MyDslCommandExtension]
public class MyCommandClass : ICommandExtension
{
/// <summary>
/// Provides access to current document and selection.
/// </summary>
[Import]
IVsSelectionContext SelectionContext { get; set; }
/// <summary>
/// Called when the user selects this command.
/// </summary>
/// <param name="command"></param>
public void Execute(IMenuCommand command)
{
// Transaction is required if you want to update elements.
using (Transaction t = SelectionContext.CurrentStore
.TransactionManager.BeginTransaction("fix names"))
{
foreach (ExampleShape shape in SelectionContext.CurrentSelection)
{
ExampleElement element = shape.ModelElement as ExampleElement;
element.Name = element.Name + " !";
}
t.Commit();
}
}
/// <summary>
/// Called when the user right-clicks the diagram.
/// Determines whether the command should appear.
/// This method should set command.Enabled and command.Visible.
/// </summary>
/// <param name="command"></param>
public void QueryStatus(IMenuCommand command)
{
command.Enabled =
command.Visible = (SelectionContext.CurrentSelection.OfType<ExampleShape>().Count() > 0);
}
/// <summary>
/// Called when the user right-clicks the diagram.
/// Determines the text of the command in the menu.
/// </summary>
public string Text
{
get { return "My menu command"; }
}
}
}
Controladores de gestos
Un controlador de gestos puede tratar con los objetos arrastrados al diagrama de cualquier parte, dentro o fuera Visual Studio.El ejemplo siguiente permite al usuario arrastrar archivos de Explorador de Windows al diagrama.Crea elementos que contienen los nombres de archivo.
Puede escribir controladores para tratar con arrastra de otros modelos ADSL y los modelos UML.Para obtener más información, vea Cómo: Agregar un controlador para arrastrar y colocar.
using System.ComponentModel.Composition;
using System.Linq;
using Company.MyDsl;
using Company.MyDsl.ExtensionEnablement;
using Microsoft.VisualStudio.Modeling; // Transactions
using Microsoft.VisualStudio.Modeling.Diagrams;
using Microsoft.VisualStudio.Modeling.Diagrams.ExtensionEnablement;
using Microsoft.VisualStudio.Modeling.ExtensionEnablement;
namespace MefExtension
{
[MyDslGestureExtension]
class MyGestureExtension : IGestureExtension
{
public void OnDoubleClick(ShapeElement targetElement, DiagramPointEventArgs diagramPointEventArgs)
{
System.Windows.Forms.MessageBox.Show("double click!");
}
/// <summary>
/// Called when the user drags anything over the diagram.
/// Return true if the dragged object can be dropped on the current target.
/// </summary>
/// <param name="targetMergeElement">The shape or diagram that the mouse is currently over</param>
/// <param name="diagramDragEventArgs">Data about the dragged element.</param>
/// <returns></returns>
public bool CanDragDrop(ShapeElement targetMergeElement, DiagramDragEventArgs diagramDragEventArgs)
{
// This handler only allows items to be dropped onto the diagram:
return targetMergeElement is MefDsl2Diagram &&
// And only accepts files dragged from Windows Explorer:
diagramDragEventArgs.Data.GetFormats().Contains("FileNameW");
}
/// <summary>
/// Called when the user drops an item onto the diagram.
/// </summary>
/// <param name="targetDropElement"></param>
/// <param name="diagramDragEventArgs"></param>
public void OnDragDrop(ShapeElement targetDropElement, DiagramDragEventArgs diagramDragEventArgs)
{
MefDsl2Diagram diagram = targetDropElement as MefDsl2Diagram;
if (diagram == null) return;
// This handler only accepts files dragged from Windows Explorer:
string[] draggedFileNames = diagramDragEventArgs.Data.GetData("FileNameW") as string[];
if (draggedFileNames == null || draggedFileNames.Length == 0) return;
using (Transaction t = diagram.Store.TransactionManager.BeginTransaction("file names"))
{
// Create an element to represent each file:
foreach (string fileName in draggedFileNames)
{
ExampleElement element = new ExampleElement(diagram.ModelElement.Partition);
element.Name = fileName;
// This method of adding the new element allows the position
// of the shape to be specified:
ElementGroup group = new ElementGroup(element);
diagram.ElementOperations.MergeElementGroupPrototype(
diagram, group.CreatePrototype(), PointD.ToPointF(diagramDragEventArgs.MousePosition));
}
t.Commit();
}
}
}
}
Restricciones de validación
Los métodos de validación se marcan con el atributo de ValidationExtension generado por DSL, y por ValidationMethodAttribute.El método puede aparecer en cualquier clase que no esté marcada por un atributo.
Para obtener más información, vea La validación en los lenguajes específicos de dominio.
using Company.MyDsl;
using Company.MyDsl.ExtensionEnablement;
using Microsoft.VisualStudio.Modeling.Validation;
namespace MefExtension
{
class MyValidationExtension // Can be any class.
{
// SAMPLE VALIDATION METHOD.
// All validation methods have the following attributes.
// Specific to the extended DSL:
[MyDslValidationExtension]
// Determines when validation is applied:
[ValidationMethod(
ValidationCategories.Save
| ValidationCategories.Open
| ValidationCategories.Menu)]
/// <summary>
/// When validation is executed, this method is invoked
/// for every element in the model that is an instance
/// of the second parameter type.
/// </summary>
/// <param name="context">For reporting errors</param>
/// <param name="elementToValidate"></param>
private void ValidateClassNames
(ValidationContext context,
// Type determines to what elements this will be applied:
ExampleElement elementToValidate)
{
// Write code here to test values and links.
if (elementToValidate.Name.IndexOf(' ') >= 0)
{
// Log any unacceptable values:
context.LogError(
// Description:
"Name must not contain spaces"
// Error code unique to this type of error:
, "MyDsl001"
// Element to highlight when user double-clicks error:
, elementToValidate);
} } } }
Vea también
Conceptos
Managed Extensibility Framework (MEF)
Cómo: Agregar un controlador para arrastrar y colocar
La validación en los lenguajes específicos de dominio