MEF를 사용하여 DSL 확장

확장성 프레임 워크 (MEF) 관리를 사용 하 여 도메인 관련 언어를 (DSL) exntend 있습니다.사용자나 다른 개발자가 DSL 정의 하 고 프로그램 코드를 변경 하지 않고는 DSL에 대 한 확장을 작성할 수 있습니다.그러한 확장 메뉴 명령, 끌어서 놓기 처리기 및 유효성 검사를 포함합니다.사용자를 DSL을 설치 하 고 다음 필요에 따라 확장을 설치 수 있습니다.

MEF는 DSL을 사용 하는 경우 모두 DSL과 함께 작성 된 경우에 또한이 쉽게 기능을 DSL 작성할 수 수 있습니다.

MEF에 대 한 자세한 내용은 참조 하십시오. MEF(Managed Extensibility Framework).

MEF에서 확장 하 여 DSL을 사용 하려면

  1. 라는 새 폴더를 만듭니다 MefExtension 내부에서 DslPackage 프로젝트입니다.다음 파일을 추가 합니다.

    파일 이름

    파일 내용

    CommandExtensionVSCT.tt

    중요중요
    GUID에서이 파일을 Dslpackage\generatedcode\constants.tt에서 정의 된 GUID CommandSetId 수 설정
    <#@ 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

    이 파일을 추가 하는 경우의 스위치 중 하나를 사용 하 여를 DSL에 유효성을 설정 해야 Editor\Validation 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" #>
  2. 라는 새 폴더를 만듭니다 MefExtension 내부에서 Dsl 프로젝트입니다.다음 파일을 추가 합니다.

    파일 이름

    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" #>
  3. 지정 된 기존 파일에 다음 줄을 추가 합니다. DslPackage\Commands.vsct:

    <Include href="MefExtension\CommandExtensionVSCT.vsct"/>
    

    기존 후 줄 삽입 <Include> 지시문입니다.

  4. Dsldefinition.dsl를 엽니다.

  5. DSL 탐색기 선택 Editor\Validation.

  6. 속성 창에서 속성을 하나 이상 이라는 것이 있는지 확인 하십시오 사용 하 여... is true.

  7. 솔루션 탐색기 도구 모음에서 모든 템플릿 변환.

    보조 파일은 각 추가 파일 아래 나타납니다.

  8. 빌드한 후 솔루션 여전히 작동 하는지 확인 합니다.

이제를 DSL MEF 사용이 가능 합니다.MEF 확장으로는 메뉴 명령, 제스처 처리기 및 유효성 검사 제약 조건을 작성할 수 있습니다.다른 사용자 지정 코드와 함께 DSL 솔루션에서 이러한 확장을 작성할 수 있습니다.또한 사용자나 다른 개발자가 별도 쓸 수 있습니다 Visual Studio 를 DSL을 확장 하는 확장입니다.

MEF 가능한 DSL에 대 한 확장 만들기

자신이 나 다른 사용자가 만든 MEF 가능한 DSL에 액세스할 수 있으면 확장을 작성할 수 있습니다.메뉴 명령, 제스처 처리기 또는 유효성 검사 제약 조건을 추가 하는 확장을 사용할 수 있습니다.이러한 확장을 작성 하려면 사용 하는 Visual Studio 확장명 (VSIX) 솔루션입니다.솔루션 두 부분으로 이루어져 있습니다: 코드 어셈블리를 작성 하는 클래스 라이브러리 프로젝트와 어셈블리 패키지 VSIX 프로젝트입니다.

DSL 확장 VSIX 생성 하기

  1. 새 클래스 라이브러리 프로젝트를 만듭니다.이렇게 하는 새 프로젝트 선택 대화 상자에서 Visual Basic 또는 C# 다음 선택 클래스 라이브러리.

  2. 새 클래스 라이브러리 프로젝트에는 DSL의 어셈블리에 참조를 추가 합니다.

    • 이 어셈블리는 일반적으로 끝나는 이름이 있습니다 ".Dsl.dll "입니다.

    • DSL 프로젝트에 액세스할 수 있으면 디렉터리 아래에 있는 어셈블리 파일을 찾을 수 있습니다.Dsl\bin\*

    • DSL VSIX 파일에 액세스할 경우에 ".zip" VSIX 파일의 파일 이름 확장명을 변경 하 여 어셈블리를 찾을 수 있습니다..Zip 파일의 압축을 풀.

  3. 다음 .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

  4. VSIX 프로젝트가 동일한 솔루션에 만듭니다.에 이렇게 하는 새 프로젝트 대화 상자에서 확장 Visual Basic 또는 C#, 클릭 확장성, 다음을 선택 하 고 VSIX 프로젝트.

  5. 솔루션 탐색기에서 VSIX 프로젝트를 마우스 오른쪽 단추로 클릭 하 고 다음을 클릭 시작 프로젝트로 설정.

  6. 새 프로젝트를 열고 source.extension.vsixmanifest.

  7. 콘텐츠 추가를 클릭합니다.대화 상자에서 설정 콘텐츠 형식MEF 구성 요소, 및 소스 프로젝트 클래스 라이브러리 프로젝트입니다.

  8. DSL VSIX 참조를 추가 합니다.

    1. source.extension.vsixmanifest를 클릭 참조 추가

    2. 대화 상자에서 누릅니다 추가 페이로드 하 여 DSL의 VSIX 파일을 찾습니다.VSIX 파일 DSL 솔루션에서에 빌드됩니다 DslPackage\bin\*.

      이 사용자가 DSL 및 확장을 동시에 설치할 수 있습니다.DSL 사용자를 이미 설치한 경우 확장만 설치 됩니다.

  9. 검토 하 고 업데이트 필드에 source.extension.vsixmanifest.클릭 버전 선택 확인 하 고 올바른 Visual Studio 버전으로 설정 합니다.

  10. 클래스 라이브러리 프로젝트에 코드를 추가 합니다.예제는 다음 단원에서 지침으로 사용 합니다.

    다양 한 제스처를 명령과 유효성 검사 클래스를 추가할 수 있습니다.

  11. 키를 눌러 확장 테스트 합니다 F5.실험의 인스턴스에서 Visual Studio, 만들기 또는 DSL의 대 한 예제 파일을 엽니다.

MEF 확장에 대 한 Dsl 작성

어셈블리 코드를 별도 DSL 확장 솔루션의 프로젝트에서 확장을 작성할 수 있습니다.DSL의 일부로 명령과 제스처, 유효성 검사 코드를 작성 하는 편리한 방법으로 MEF에서 DslPackage 프로젝트를 사용할 수도 있습니다.

Ff972471.collapse_all(ko-kr,VS.110).gif메뉴 명령

메뉴 명령을 작성 하려면 구현 하는 클래스를 정의 합니다. ICommandExtension 및 DSL에 라는 사용자 정의 속성을 가진 클래스 접두사 YourDslCommandExtension.여러 개의 메뉴 명령을 클래스를 작성할 수 있습니다.

QueryStatus()사용자가 다이어그램을 마우스 오른쪽 단추로 클릭할 때마다 호출 됩니다.현재 선택 영역을 검사 하 고 설정 해야 command.Enabled 명령을 적용할 수 있는 경우를 나타낼 수 있습니다.

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"; }
    }
  }
}

Ff972471.collapse_all(ko-kr,VS.110).gif제스처 처리기

제스처 처리기 내부 또는 외부를 다이어그램으로 끌어다 원하는 위치에서 끌어 개체를 처리할 수 있습니다 Visual Studio.다음 예제에서는 파일 Windows 탐색기에서 다이어그램으로 끌 수가 있습니다.파일 이름이 들어 있는 요소를 만듭니다.

다른 DSL 모델 및 UML 모델의 끌으로 처리 하는 처리기를 작성할 수 있습니다.자세한 내용은 방법: 끌어서 놓기 처리기 추가를 참조하십시오.

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();
      }
    }
  }
}

Ff972471.collapse_all(ko-kr,VS.110).gif유효성 검사 제약 조건

유효성 검사 메서드가 표시 되어가 ValidationExtension DSL, 고도 생성 되는 특성이 ValidationMethodAttribute.메서드 특성에 의해 표시 되지 않은 모든 클래스에 나타날 수 있습니다.

자세한 내용은 도메인별 언어에서 유효성 검사를 참조하십시오.

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); 
} } } }

참고 항목

개념

MEF(Managed Extensibility Framework)

방법: 끌어서 놓기 처리기 추가

도메인별 언어에서 유효성 검사

기타 리소스

VSIX 배포