텍스트 템플릿에서 Visual Studio ModelBus 사용
Visual Studio ModelBus 참조가 포함된 모델을 읽는 텍스트 템플릿을 작성하는 경우 참조를 확인하여 대상 모델에 액세스해야 할 수 있습니다. 이 경우 텍스트 템플릿 및 참조된 DSL(Domain-Specific Language)을 조정해야 합니다.
참조의 대상인 DSL에는 텍스트 템플릿에서 액세스하도록 구성된 ModelBus 어댑터가 있어야 합니다. 다른 코드에서도 DSL에 액세스하는 경우 표준 ModelBus 어댑터 외에 다시 구성된 어댑터가 필요합니다.
어댑터 관리자는 VsTextTemplatingModelingAdapterManager에서 상속해야 하며
[HostSpecific(HostName)]
특성이 있어야 합니다.템플릿은 ModelBusEnabledTextTransformation에서 상속해야 합니다.
참고 항목
ModelBus 참조를 포함하지 않는 DSL 모델을 읽으려면 DSL 프로젝트에서 생성된 지시문 프로세서를 사용할 수 있습니다. 자세한 내용은 텍스트 템플릿에서 모델 액세스를 참조하세요.
텍스트 템플릿에 대한 자세한 내용은 T4 텍스트 템플릿을 사용하여 디자인 타임 코드 생성을 참조하세요.
텍스트 템플릿에서 액세스하기 위한 Model Bus 어댑터 만들기
텍스트 템플릿에서 ModelBus 참조를 확인하려면 대상 DSL에 호환되는 어댑터가 있어야 합니다. 텍스트 템플릿은 Visual Studio 문서 편집기와는 별도의 AppDomain에서 실행되므로 어댑터는 DTE를 통해 모델에 액세스하는 것이 아니라 모델을 로드해야 합니다.
대상 DSL 솔루션에 ModelBusAdapter 프로젝트가 없는 경우 Modelbus 확장 마법사를 사용하여 하나 만듭니다.
Visual Studio ModelBus 확장을 다운로드하여 설치합니다(아직 설치하지 않은 경우). 자세한 내용은 시각화 및 모델링 SDK를 참조하세요.
DSL 정의 파일을 엽니다. 디자인 화면을 마우스 오른쪽 단추로 클릭하고 Modelbus 사용을 클릭합니다.
대화 상자에서 ModelBus에 이 DSL 표시를 선택합니다. 이 DSL을 모델에 표시하는 동시에 다른 DSL에 대한 참조도 사용하려는 경우 두 옵션을 모두 선택하면 됩니다.
확인을 클릭합니다. "ModelBusAdapter"라는 새 프로젝트가 DSL 솔루션에 추가됩니다.
모든 템플릿 변환을 클릭합니다.
솔루션을 다시 빌드합니다.
텍스트 템플릿에서 또한 명령과 같은 다른 코드에서 DSL에 액세스하려면 ModelBusAdapter 프로젝트를 복제합니다.
Windows 탐색기에서 ModelBusAdapter.csproj가 포함된 폴더를 복사하여 붙여넣습니다.
프로젝트 파일의 이름을 바꿉니다(예: T4ModelBusAdapter.csproj).
솔루션 탐색기에서 솔루션 노드를 마우스 오른쪽 단추로 클릭하고 추가를 가리킨 다음 기존 프로젝트를 클릭합니다. 새 어댑터 프로젝트 T4ModelBusAdapter.csproj를 찾습니다.
새 프로젝트의 각
*.tt
파일에서 네임스페이스를 변경합니다.솔루션 탐색기에서 새 프로젝트를 마우스 오른쪽 단추로 클릭하고 속성을 클릭합니다. 속성 편집기에서 생성된 어셈블리의 이름과 기본 네임스페이스를 변경합니다.
DslPackage 프로젝트에서 새 어댑터 프로젝트에 대한 참조를 추가하여 두 어댑터 모두에 대한 참조가 포함되도록 합니다.
DslPackage\source.extension.tt에서 새 어댑터 프로젝트를 참조하는 줄을 추가합니다.
<MefComponent>|T4ModelBusAdapter|</MefComponent>
모든 템플릿 변환을 클릭하고 솔루션을 다시 빌드합니다. 빌드 오류가 발생하지 않을 것입니다.
세 어댑터 프로젝트에서 다음 어셈블리에 대한 참조를 추가합니다.
- Microsoft.VisualStudio.TextTemplating.11.0
- Microsoft.VisualStudio.TextTemplating.Modeling.11.0
AdapterManager.tt에서
VsTextTemplatingModelingAdapterManager에서 상속하도록 AdapterManagerBase의 선언을 변경합니다.
public partial class <#= dslName =>AdapterManagerBase :
Microsoft.VisualStudio.TextTemplating.Modeling.VsTextTemplatingModelingAdapterManager { ...
파일 끝 부근에서 AdapterManager 클래스 앞에 있는 HostSpecific 특성을 바꿉니다. 다음 줄을 제거합니다.
[DslIntegration::HostSpecific(DslIntegrationShell::VsModelingAdapterManager.HostName)]
다음 줄을 삽입합니다.
[Microsoft.VisualStudio.Modeling.Integration.HostSpecific(HostName)]
이 특성은 modelbus 소비자가 어댑터를 검색할 때 사용할 수 있는 어댑터 집합을 필터링합니다.
모든 템플릿 변환을 클릭하고 솔루션을 다시 빌드합니다. 빌드 오류가 발생하지 않을 것입니다.
ModelBus 참조를 확인할 수 있는 텍스트 템플릿 작성
일반적으로 "원본" DSL에서 파일을 읽고 생성하는 템플릿으로 시작합니다. 이 템플릿은 원본 DSL 프로젝트에서 생성된 지시문을 사용하여 텍스트 템플릿에서 모델 액세스에 설명된 방식으로 원본 모델 파일을 읽습니다. 그러나 원본 DSL에는 "대상" DSL에 대한 ModelBus 참조가 포함되어 있습니다. 이러한 참조를 해결하고 대상 DSL에 액세스하기 위해 템플릿 코드를 사용하도록 설정해야 합니다. 따라서 다음 단계에 따라 템플릿을 조정해야 합니다.
템플릿의 기본 클래스를 ModelBusEnabledTextTransformation으로 변경합니다.
템플릿 지시문에
hostspecific="true"
를 포함합니다.대상 DSL 및 해당 어댑터에 어셈블리 참조를 추가하고 ModelBus를 사용하도록 설정합니다.
대상 DSL의 일부로 생성되는 지시문은 필요하지 않습니다.
<#@ template debug="true" hostspecific="true" language="C#"
inherits="Microsoft.VisualStudio.TextTemplating.Modeling.ModelBusEnabledTextTransformation" #>
<#@ SourceDsl processor="SourceDslDirectiveProcessor" requires="fileName='Sample.source'" #>
<#@ output extension=".txt" #>
<#@ assembly name = "Microsoft.VisualStudio.Modeling.Sdk.Integration.11.0" #>
<#@ assembly name = "Company.TargetDsl.Dsl.dll" #>
<#@ assembly name = "Company.TargetDsl.T4ModelBusAdapter.dll" #>
<#@ assembly name = "System.Core" #>
<#@ import namespace="Microsoft.VisualStudio.Modeling.Integration" #>
<#@ import namespace="Company.TargetDsl" #>
<#@ import namespace="Company.TargetDsl.T4ModelBusAdapters" #>
<#@ import namespace="System.Linq" #>
<#
SourceModelRoot source = this.ModelRoot; // Usual access to source model.
// In the source DSL Definition, the root element has a model reference:
using (TargetAdapter adapter = this.ModelBus.CreateAdapter(source.ModelReference) as TargetAdapter)
{if (adapter != null)
{
// Get the root of the target model:
TargetRoot target = adapter.ModelRoot;
// The source DSL Definition has a class "SourceElement" embedded under the root.
// (Let's assume they're all in the same model file):
foreach (SourceElement sourceElement in source.Elements)
{
// In the source DSL Definition, each SourceElement has an MBR property:
ModelBusReference elementReference = sourceElement.ReferenceToTarget;
// Resolve the target model element:
TargetElement element = adapter.ResolveElementReference<TargetElement>(elementReference);
#>
The source <#= sourceElement.Name #> is linked to: <#= element.Name #> in target model: <#= target.Name #>.
<#
}
}}
// Other useful code: this.Host.ResolvePath(filename) gets an absolute filename
// from a path that is relative to the text template.
#>
이 텍스트 템플릿이 실행되면 SourceDsl
지시문이 Sample.source
파일을 로드합니다. 템플릿은 this.ModelRoot
부터 해당 모델의 요소에 액세스할 수 있습니다. 코드는 해당 DSL의 도메인 클래스 및 속성을 사용할 수 있습니다.
또한 템플릿은 ModelBus 참조를 확인할 수 있습니다. 참조가 대상 모델을 가리키는 경우 어셈블리 지시문을 사용하면 코드에서 해당 모델의 DSL의 도메인 클래스 및 속성을 사용할 수 있습니다.
DSL 프로젝트에서 생성된 지시문을 사용하지 않는 경우 다음도 포함해야 합니다.
<#@ assembly name = "Microsoft.VisualStudio.Modeling.Sdk.11.0" #> <#@ assembly name = "Microsoft.VisualStudio.TextTemplating.Modeling.11.0" #>
this.ModelBus
를 사용하여 ModelBus에 대한 액세스 권한을 얻습니다.
연습: ModelBus를 사용하는 텍스트 템플릿 테스트
이 연습에서는 다음과 같은 단계를 수행합니다.
두 개의 DSL을 생성합니다. 한 DSL인 소비자에는 다른 DSL인 공급자를 참조할 수 있는
ModelBusReference
속성이 있습니다.공급자에 두 개의 ModelBus 어댑터를 만듭니다. 하나는 텍스트 템플릿에서 액세스하기 위한 어댑터이고, 다른 하나는 일반 코드용입니다.
단일 실험적 프로젝트에서 DSL의 인스턴스 모델을 만듭니다.
한 모델에서 다른 모델을 가리키도록 도메인 속성을 설정합니다.
가리킨 모델을 여는 두 번 클릭 처리기를 작성합니다.
첫 번째 모델을 로드하고, 다른 모델에 대한 참조를 따르고, 다른 모델을 읽을 수 있는 텍스트 템플릿을 작성합니다.
ModelBus에 액세스할 수 있는 DSL 생성
새 DSL 솔루션을 만듭니다. 이 예제를 위해 작업 흐름 솔루션 템플릿을 선택합니다. 언어 이름을
MBProvider
로 설정하고 파일 이름 확장명을 ".provide"로 설정합니다.DSL 정의 다이어그램에서 맨 위에 있지 않은 다이어그램의 빈 부분을 마우스 오른쪽 단추로 클릭한 다음 Modelbus 사용을 클릭합니다.
Modelbus 사용이 표시되지 않으면 VMSDK ModelBus 확장을 다운로드하여 설치합니다.
Modelbus 사용 대화 상자에서 ModelBus에 이 DSL 표시를 선택하고 확인을 클릭합니다.
새 프로젝트(
ModelBusAdapter
)가 솔루션에 추가됩니다.
이제 ModelBus를 통해 텍스트 템플릿에서 액세스할 수 있는 DSL이 있습니다. 이에 대한 참조는 명령, 이벤트 처리기 또는 규칙 코드에서 확인할 수 있으며, 모두 모델 파일 편집기의 AppDomain에서 작동합니다. 그러나 텍스트 템플릿은 별도의 AppDomain에서 실행되며 편집할 때 모델에 액세스할 수 없습니다. 텍스트 템플릿에서 이 DSL에 대한 ModelBus 참조에 액세스하려면 별도의 ModelBusAdapter가 있어야 합니다.
텍스트 템플릿에 대해 구성된 ModelBus 어댑터 만들기
파일 탐색기에서 ModelBusAdapter.csproj가 포함된 폴더를 복사하여 붙여넣습니다.
폴더 이름을 T4ModelBusAdapter로 지정합니다.
프로젝트 파일의 이름을 T4ModelBusAdapter.csproj로 바꿉니다.
솔루션 탐색기에서 T4ModelBusAdapter를 MBProvider 솔루션에 추가합니다. 솔루션 노드를 마우스 오른쪽 단추로 클릭하고 추가를 가리킨 후 기존 프로젝트를 클릭합니다.
T4ModelBusAdapter 프로젝트 노드를 마우스 오른쪽 단추로 클릭한 다음 속성을 클릭합니다. 프로젝트 속성 창에서 어셈블리 이름 및 기본 네임스페이스를
Company.MBProvider.T4ModelBusAdapters
로 변경합니다.T4ModelBusAdapter의 각 *.tt 파일에서 줄이 다음과 같이 표시되도록 네임스페이스의 마지막 부분에 "T4"를 삽입합니다.
namespace <#= CodeGenerationUtilities.GetPackageNamespace(this.Dsl) #>.T4ModelBusAdapters
DslPackage
프로젝트에서T4ModelBusAdapter
에 대한 프로젝트 참조를 추가합니다.DslPackage\source.extension.tt에서
<Content>
아래에 다음 줄을 추가합니다.<MefComponent>|T4ModelBusAdapter|</MefComponent>
T4ModelBusAdapter
프로젝트에서 Microsoft.VisualStudio.TextTemplating.Modeling.11.0에 대한 참조를 추가합니다.T4ModelBusAdapter\AdapterManager.tt를 엽니다.
AdapterManagerBase의 기본 클래스를 VsTextTemplatingModelingAdapterManager로 변경합니다. 파일의 이 부분은 이제 다음과 같이 표시됩니다.
namespace <#= CodeGenerationUtilities.GetPackageNamespace(this.Dsl) #>.T4ModelBusAdapters { /// <summary> /// Adapter manager base class (double derived pattern) for the <#= dslName #> Designer /// </summary> public partial class <#= dslName #>AdapterManagerBase : Microsoft.VisualStudio.TextTemplating.Modeling.VsTextTemplatingModelingAdapterManager {
파일 끝 부근에서 AdapterManager 클래스 앞에 다음 추가 특성을 삽입합니다.
[Microsoft.VisualStudio.Modeling.Integration.HostSpecific(HostName)]
결과는 다음과 같습니다.
/// <summary> /// ModelBus modeling adapter manager for a <#= dslName #>Adapter model adapter /// </summary> [Mef::Export(typeof(DslIntegration::ModelBusAdapterManager))] [Mef::ExportMetadata(DslIntegration::CompositionAttributes.AdapterIdKey,<#= dslName #>Adapter.AdapterId)] [DslIntegration::HostSpecific(DslIntegrationShell::VsModelingAdapterManager.HostName)] [Microsoft.VisualStudio.Modeling.Integration.HostSpecific(HostName)] public partial class <#= dslName #>AdapterManager : <#= dslName #>AdapterManagerBase { }
솔루션 탐색기의 제목 표시줄에서 모든 템플릿 변환을 클릭합니다.
F5키를 누릅니다.
DSL이 작동하는지 확인합니다. 실험적 프로젝트에서
Sample.provider
를 엽니다. Visual Studio의 실험적 인스턴스를 닫습니다.이제 이 DSL에 대한 ModelBus 참조를 텍스트 템플릿 및 일반 코드에서 확인할 수 있습니다.
ModelBus Reference 도메인 속성을 사용하여 DSL 생성
최소 언어 솔루션 템플릿을 사용하여 새 DSL을 만듭니다. 언어 이름을 MBConsumer로 지정하고 파일 이름 확장명을 ".consume"으로 설정합니다.
DSL 프로젝트에서 MBProvider DSL 어셈블리에 대한 참조를 추가합니다.
MBConsumer\Dsl\References
를 마우스 오른쪽 단추로 클릭한 다음 참조 추가를 클릭합니다. 찾아보기 탭에서MBProvider\Dsl\bin\Debug\Company.MBProvider.Dsl.dll
를 찾습니다.그러면 다른 DSL을 사용하는 코드를 만들 수 있습니다. 여러 DSL에 대한 참조를 만들려는 경우 해당 DSL도 추가합니다.
DSL 정의 다이어그램에서 다이어그램을 마우스 오른쪽 단추로 클릭하고 ModelBus 사용을 클릭합니다. 대화 상자에서 이 DSL이 ModelBus를 사용하도록 설정을 선택합니다.
ExampleElement
클래스에서 새 도메인 속성MBR
을 추가하고, 속성 창에서 해당 형식을ModelBusReference
로 설정합니다.다이어그램에서 도메인 속성을 마우스 오른쪽 단추로 클릭하고 ModelBusReference 관련 속성 편집을 클릭합니다. 대화 상자에서 모델 요소를 선택합니다.
파일 대화 상자 필터를 다음으로 설정합니다.
Provider File|*.provide
“|” 뒤의 substring은 파일 선택 대화 상자용 필터입니다. *.*를 사용하여 모든 파일을 허용하도록 설정할 수도 있습니다.
모델 요소 형식 목록에서 공급자 DSL(예: Company.MBProvider.Task)에 하나 이상의 도메인 클래스 이름을 입력합니다. 이들은 추상 클래스일 수 있습니다. 이 목록을 비워두면 사용자가 임의의 요소에 대한 참조를 설정할 수 있습니다.
대화 상자를 닫고 모든 템플릿을 변환합니다.
다른 DSL의 요소에 대한 참조를 포함할 수 있는 DSL이 만들어졌습니다.
솔루션의 다른 파일에 대한 ModelBus 참조 만들기
MBConsumer 솔루션에서 CTRL+F5를 누릅니다. Visual Studio 실험적 인스턴스가 MBConsumer\Debugging 프로젝트에서 열립니다.
Sample.provide의 복사본을 MBConsumer\Debugging 프로젝트에 추가합니다. ModelBus 참조는 동일한 솔루션에 있는 파일을 참조해야 하기 때문에 이 작업이 필요합니다.
디버깅 프로젝트를 마우스 오른쪽 단추로 클릭하고 추가를 가리킨 다음 기존 항목을 클릭합니다.
항목 추가 대화 상자에서 필터를 모든 파일(*.*)로 설정합니다.
MBProvider\Debugging\Sample.provide
로 이동하여 추가를 클릭합니다.
Sample.consume
을(를) 여십시오.한 예제 도형을 클릭하고 속성 창에서 MBR 속성의 [...]를 클릭합니다. 대화 상자에서 찾아보기를 클릭하고
Sample.provide
를 선택합니다. 요소 창에서 작업 형식을 확장하고 요소 중 하나를 선택합니다.파일을 저장합니다. (Visual Studio 실험적 인스턴스를 아직 닫지 마세요.)
다른 모델의 요소에 대한 ModelBus 참조를 포함하는 모델이 만들어졌습니다.
텍스트 템플릿에서 ModelBus 참조 확인
Visual Studio 실험적 인스턴스에서 샘플 텍스트 템플릿 파일을 엽니다. 해당 내용을 다음과 같이 설정합니다.
<#@ template debug="true" hostspecific="true" language="C#" inherits="Microsoft.VisualStudio.TextTemplating.Modeling.ModelBusEnabledTextTransformation" #> <#@ MBConsumer processor="MBConsumerDirectiveProcessor" requires="fileName='Sample.consume'" #> <#@ output extension=".txt" #> <#@ assembly name = "Microsoft.VisualStudio.Modeling.Sdk.Integration.11.0" #> <#@ assembly name = "Company.MBProvider.Dsl.dll" #> <#@ import namespace="Microsoft.VisualStudio.Modeling.Integration" #> <#@ import namespace="Company.MBProvider" #> <# // Property provided by the Consumer directive processor: ExampleModel consumerModel = this.ExampleModel; // Iterate through Consumer model, listing the elements: foreach (ExampleElement element in consumerModel.Elements) { #> <#= element.Name #> <# if (element.MBR != null) using (ModelBusAdapter adapter = this.ModelBus.CreateAdapter(element.MBR)) { // If we allowed multiple types or DSLs in the MBR, discover type here. Task task = adapter.ResolveElementReference<Task>(element.MBR); #> <#= element.Name #> is linked to Task: <#= task==null ? "(null)" : task.Name #> <# } } #>
다음 사항을 확인합니다.
template
지시문의hostSpecific
및inherits
특성을 설정해야 합니다.소비자 모델은 일반적으로 해당 DSL에서 생성된 지시문 프로세서를 통해 액세스됩니다.
어셈블리 및 가져오기 지시문은 ModelBus와 공급자 DSL의 형식에 액세스할 수 있어야 합니다.
여러 MBR이 동일한 모델에 연결되어 있는 경우 CreateAdapter를 한 번만 호출하는 것이 좋습니다.
템플릿을 저장하는 경우 결과 텍스트 파일이 다음과 같은지 확인합니다.
ExampleElement1 ExampleElement2 ExampleElement2 is linked to Task: Task2
제스처 처리기에서 ModelBus 참조 확인
Visual Studio 실험적 인스턴스가 실행 중이면 닫습니다.
MBConsumer\Dsl\Custom.cs라는 파일을 추가하고 해당 내용을 다음으로 설정합니다.
namespace Company.MB2Consume { using Microsoft.VisualStudio.Modeling.Integration; using Company.MB3Provider; public partial class ExampleShape { public override void OnDoubleClick(Microsoft.VisualStudio.Modeling.Diagrams.DiagramPointEventArgs e) { base.OnDoubleClick(e); ExampleElement element = this.ModelElement as ExampleElement; if (element.MBR != null) { IModelBus modelbus = this.Store.GetService(typeof(SModelBus)) as IModelBus; using (ModelBusAdapter adapter = modelbus.CreateAdapter(element.MBR)) { Task task = adapter.ResolveElementReference<Task>(element.MBR); // Open a window on this model: ModelBusView view = adapter.GetDefaultView(); view.Show(); view.SetSelection(element.MBR); } } } } }
Ctrl+F5를 누릅니다.
Visual Studio 실험적 인스턴스에서
Debugging\Sample.consume
을 엽니다.한 도형을 두 번 클릭합니다.
해당 요소에서 MBR을 설정한 경우 참조된 모델이 열리고 참조된 요소가 선택됩니다.
관련 콘텐츠
참고 항목
텍스트 템플릿 변환 구성 요소는 Visual Studio 확장 개발 워크로드의 일부로 자동으로 설치됩니다. Visual Studio 설치 프로그램의 개별 구성 요소 탭, SDK, 라이브러리, 프레임워크 범주 아래에서 설치할 수도 있습니다. 개별 구성 요소 탭에서 Modeling SDK 구성 요소를 설치합니다.