Rozšíření vašeho DSL pomocí MEF
Exntend jazyk (DSL) specifické pro doménu pomocí můžete spravované Extensibility Framework (MEF).Nebo jinými vývojáři budou moci psát rozšíření pro modem DSL bez změny definice DSL a kód programu.Takové rozšíření zahrnovat příkazy nabídky, obslužné rutiny a přetažení a ověření.Uživatelé budou moci nainstalovat vaše DSL a volitelně rozšíření nainstalovat jej.
Navíc pokud povolíte MEF ve vašem DSL, může být snadněji zapsat některé funkce vašeho DSL i v případě, že jsou všechny postaveny spolu s modem DSL.
Další informace o MEF viz Managed Extensibility Framework (MEF).
Vaše DSL na MEF prodloužit povolení
Vytvořit novou složku s názvem MefExtension uvnitř DslPackage projektu.Do ní přidáte následující soubory:
Název souboru
Obsah souboru
CommandExtensionVSCT.tt
Důležité Nastavit identifikátor GUID v tomto souboru je stejný jako identifikátor GUID CommandSetId, který je definován v 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
Pokud přidáte tento soubor, musíte povolit ověření ve vašem DSL pomocí alespoň jeden z přepínačů v Editor\Validation v aplikaci Explorer DSL.
<#@ 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" #>
Vytvořit novou složku s názvem MefExtension uvnitř Dsl projektu.Do ní přidáte následující soubory:
Název souboru
Obsah
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" #>
Přidejte následující řádek do existující soubor s názvem DslPackage\Commands.vsct:
<Include href="MefExtension\CommandExtensionVSCT.vsct"/>
Vložit řádek za stávající <Include> směrnice.
Otevřete DslDefinition.dsl.
Vyberte v aplikaci Explorer DSL, Editor\Validation.
V okně Vlastnosti zkontrolujte, alespoň jeden z vlastnosti pojmenované používá... is true.
V panelu nástrojů v aplikaci Solution Explorer klepněte na Transformace všechny šablony.
Podpůrné soubory, které se zobrazí pod jednotlivé soubory, které jste přidali.
Sestavit a spustit řešení ověřte, zda je stále funkční.
Vaše DSL je nyní povolena MEF.Příkazy nabídky, obslužné rutiny gest a ověření omezení lze zapsat jako MEF rozšíření.Tato rozšíření můžete psát v DSL řešení spolu s jiným vlastním kódem.Kromě toho jste nebo jinými vývojáři psát samostatné Visual Studio rozšíření, které rozšiřují vaše DSL.
Vytváření rozšíření pro DSL MEF povoleno
Pokud máte přístup k DSL povoleno MEF vytvořili sami sobě nebo někomu jinému, můžete psát rozšíření pro něj.Rozšíření lze přidat příkazy nabídky, obslužné rutiny gesta nebo omezení ověření.Chcete-li tyto přípony, použijte Visual Studio řešení rozšíření (VSIX).Roztok má dvě části: projekt knihovny třídy, který vytvoří sestavení kódu a VSIX projektu, že balíčky sestavení.
Vytvořit DSL rozšíření VSIX
Vytvořte nový projekt knihovny tříd.V tomto postupu Nový projekt vyberte položku jazyka Visual Basic nebo Visual C# a vyberte Knihovna tříd.
V novém projektu knihovny třídy přidáte odkaz na sestavení modem DSL.
Toto sestavení obvykle obsahuje název, který končí ".DSL.dll".
Pokud máte přístup k projektu DSL, můžete najít soubor sestavení v adresářiDsl\bin\*
Pokud nemáte přístup k souboru DSL VSIX můžete najít sestavení změnou příponu názvu souboru VSIX na "ZIP".Dekomprimujte soubor ZIP.
Přidáte následující odkazy.NET sestavení:
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
Vytvoření projektu VSIX ve stejné řešení.Postupujte v Nový projekt dialogové okno pole, rozbalte položku jazyka Visual Basic nebo Visual C#, klepněte na tlačítko rozšířenía pak vyberte VSIX projektu.
V aplikaci Solution Explorer klepněte pravým tlačítkem na VSIX projektu a klepněte na tlačítko nastavit jako spuštění projektu.
Otevřít v novém projektu source.extension.vsixmanifest.
Klepněte na tlačítko Přidat obsah.V dialogovém okně nastavit Typu obsahu na MEF součást, a Projektu projektu knihovny tříd.
Přidáte odkaz VSIX na modem DSL.
V source.extension.vsixmanifest, klepněte na tlačítko Přidat odkaz
V dialogovém okně klepněte na tlačítko Přidat datové části a vyhledejte soubor VSIX modem DSL.Soubor VSIX je součástí řešení DSL v DslPackage\bin\*.
To umožňuje uživatelům současně nainstalovat modem DSL a vaše rozšíření.Pokud uživatel již nainstalován modem DSL, bude nainstalována pouze vaše rozšíření.
Zkontrolovat a aktualizovat ostatní pole source.extension.vsixmanifest.Klepněte na tlačítko Vyberte vydání a ověřte, zda správné Visual Studio edice jsou nastaveny.
Přidejte kód projektu knihovny tříd.Příklady v následující části lze použijte jako vodítko.
Můžete přidat libovolný počet příkaz, gesta a ověření třídy.
Testování rozšíření stisknutím F5.Experimentální instance Visual Studio, vytvořte nebo otevřete soubor například modem DSL.
Psaní MEF rozšíření pro DSL, linky
Projekt kódu sestavení samostatné řešení rozšíření DSL můžete psát rozšíření.Můžete také MEF projekt DslPackage jako pohodlný způsob, jak psát příkazy, gesta a ověřovací kód jako součást DSL.
Příkazy nabídky
Chcete-li příkaz nabídky, definovat třídu, která implementuje ICommandExtension a předpona třída s atributem, který je definován v linka DSL s názvem YourDslCommandExtension.Můžete napsat více než jedné třídy příkazu nabídky.
QueryStatus()nazývá se vždy, když uživatel klepne pravým tlačítkem myši na diagram.Kontrolovat aktuální výběr a nastavení command.Enabled k označení, pokud je příslušný příkaz.
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"; }
}
}
}
Obslužné rutiny gesto
Popisovač tah můžete řešit objekty přetažení do diagramu odkudkoli, uvnitř nebo mimo Visual Studio.Následující příklad umožňuje uživateli přetáhněte soubory z aplikace Windows Explorer do diagramu.Vytvoří prvky, které obsahují názvy souborů.
Můžete psát obslužné rutiny pro zvládnutí drags z jiných DSL modelů a modely UML.Další informace naleznete v tématu Postupy: Přidání obslužné rutiny operace přetažení myší.
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();
}
}
}
}
Ověření omezení
Metody ověření jsou označeny ValidationExtension atribut generovaný modem DSL a také podle ValidationMethodAttribute.Metoda se mohou objevit v libovolné třídy, který není označen atributem.
Další informace naleznete v tématu Ověřování v jazyce specifickém pro doménu.
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);
} } } }
Viz také
Koncepty
Managed Extensibility Framework (MEF)
Postupy: Přidání obslužné rutiny operace přetažení myší
Ověřování v jazyce specifickém pro doménu