<#@ ExampleModel processor="<YourLanguageName>DirectiveProcessor" requires="fileName='Library.xyz'" provides="ExampleModel=LibraryModel" #>
<#@ ExampleModel processor="<YourLanguageName>DirectiveProcessor" requires="fileName='School.xyz'" provides="ExampleModel=SchoolModel" #>
<#@ ExampleModel processor="<YourLanguageName>DirectiveProcessor" requires="fileName='Work.xyz'" provides="ExampleModel=WorkModel" #>
此代码示例适用于基于最小语言解决方案模板的语言。
若要访问文本模板中的模型,你现在可以编写类似于以下示例代码的代码。
foreach (ExampleElement element in this.LibraryModel.Elements)
foreach (ExampleElement element in this.SchoolModel.Elements)
foreach (ExampleElement element in this.WorkModel.Elements)
For Each element As ExampleElement In Me.LibraryModel.Elements
For Each element As ExampleElement In Me.SchoolModel.Elements
For Each element As ExampleElement In Me.WorkModel.Elements
动态加载模型
如果要在运行时确定要加载的模型,可以在程序代码中动态加载模型文件,而不是使用特定于 DSL 的指令。
但是,特定于 DSL 的指令的功能之一是导入 DSL 命名空间,以便模板代码可以使用该 DSL 中定义的域类。 由于未使用指令,因此必须为可能加载的所有模型添加 <assembly> 和 <import> 指令。 如果可以加载的不同模型都是同一 DSL 的所有实例,那么这很简单。
若要加载该文件,最有效的方法是使用 Visual Studio ModelBus。 在典型场景中,文本模板将使用特定于 DSL 的指令以常规方式加载第一个模型。 该模型将包含对另一个模型的 ModelBus 引用。 可以使用 ModelBus 打开引用的模型并访问特定元素。 有关详细信息,请参阅在文本模板中使用 Visual Studio ModelBus。
在不太常见的情况下,你可能想要打开一个只具有文件名且不在当前 Visual Studio 项目中的模型文件。 在这种情况下,可以使用操作说明:在程序代码中从文件打开模型中所述的方法来打开文件。
从模板生成多个文件
如果要生成几个文件(例如,为模型中的每个元素生成一个单独的文件),则有几种可能的方法。 默认情况下,每个模板文件仅生成一个文件。
拆分长文件
在此方法中,你将使用一个模板生成单个文件,并用分隔符分隔。 然后,将文件拆分为其各个部分。 有两个模板,一个用于生成单个文件,另一个用于拆分。
LoopTemplate.t4 生成单个长文件。 请注意,其文件扩展名为“.t4”,因为当你单击“转换所有模板”时不应直接处理。 此模板采用参数,该参数指定分隔段的分隔符字符串:
<#@ template ninherits="Microsoft.VisualStudio.TextTemplating.VSHost.ModelingTextTransformation" #>
<#@ parameter name="delimiter" type="System.String" #>
<#@ output extension=".txt" #>
<#@ MyDSL processor="MyDSLDirectiveProcessor" requires="fileName='SampleModel.mydsl1';validation='open|load|save|menu'" #>
// Create a file segment for each element:
foreach (ExampleElement element in this.ExampleModel.Elements)
// First item is the delimiter:
<#= string.Format(delimiter, element.Id) #>
Element: <#= element.Name #>
// Here you generate more content derived from the element.
LoopSplitter.tt
调用 LoopTemplate.t4
,然后将生成的文件拆分为其各个段。 请注意,此模板不必是建模模板,因为它不会读取模型。
<#@ template hostspecific="true" language="C#" #>
<#@ output extension=".txt" #>
<#@ import namespace="Microsoft.VisualStudio.TextTemplating" #>
<#@ import namespace="System.Runtime.Remoting.Messaging" #>
<#@ import namespace="System.IO" #>
// Get the local path:
string itemTemplatePath = this.Host.ResolvePath("LoopTemplate.t4");
string dir = Path.GetDirectoryName(itemTemplatePath);
// Get the template for generating each file:
string loopTemplate = File.ReadAllText(itemTemplatePath);
Engine engine = new Engine();
// Pass parameter to new template:
string delimiterGuid = Guid.NewGuid().ToString();
string delimiter = "::::" + delimiterGuid + ":::";
CallContext.LogicalSetData("delimiter", delimiter + "{0}:::");
string joinedFiles = engine.ProcessTemplate(loopTemplate, this.Host);
string [] separateFiles = joinedFiles.Split(new string [] {delimiter}, StringSplitOptions.None);
foreach (string nameAndFile in separateFiles)
if (string.IsNullOrWhiteSpace(nameAndFile)) continue;
string[] parts = nameAndFile.Split(new string[]{":::"}, 2, StringSplitOptions.None);
if (parts.Length < 2) continue;
Generate: [<#= dir #>] [<#= parts[0] #>]
// Generate a file from this item:
File.WriteAllText(Path.Combine(dir, parts[0] + ".txt"), parts[1]);