我想在我的TT中的CS文件中使用我自己的类定义。
示例:
public class ClassDefinition
{
public string NameSpace { get; set; }
public string Name { get; set; }
public string Protection { get; set; }
List<ClassProperty> Properties { get; set; }
}
我的TT看起来像:
<#@ template debug="true" hostspecific="true" language="C#" #>
<#@ output extension=".cs" #>
<#@ assembly name="System" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="System.Xml"#>
<#@ import namespace="System.Xml" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.IO" #>
<#@ include file="$(ProjectDir)ClassDefinition.cs" #>
<#
// Read the model file
XmlDocument doc = new System.Xml.XmlDocument();
doc.Load(this.Host.ResolvePath("GeneratedXmlFile.xml"));
IList<XmlNode> nodeList = new List<XmlNode>();
foreach (XmlNode node in doc.DocumentElement)
{
switch(node.Name)
{
case "Model":
{
ClassDefinition classDefinition = new ClassDefinition();
但是我有这样的错误信息:
编译转换:找不到类型或命名空间名称“ClassDefinition”(您是否缺少using指令或程序集引用?)
我在网上查了一下并试图: - 使用包括 - 使用组装 - 使用USING 但没有任何作用。
有什么想法吗?
答案 0 :(得分:14)
以下是完整的解决方案:
1)将类分成另一个项目 2)通过TT
包括对这些类的引用<#@ assembly name="$(TargetDir)MyOwnLibraryProject.dll" #>
<#@ import namespace="MyOwnNamespace" #>
3)不要忘记在TT项目中包含此库的参考
4)您必须将MyOwnLibraryProject.dll复制到TT解决方案的BIN \ DEBUG文件夹中
5)神奇的出现!!!
每次更改DLL时都不要忘记将新版本放入文件夹:) 或者只是将Library项目输出配置为与TT项目输出相同。 我想感谢大家提供指导和想法。
答案 1 :(得分:5)
如果我理解正确,您就会尝试重复使用某个类作为模板生成的一部分。
该类本身需要在tt文件中,构建操作设置为none,自定义工具 - 什么都没有。我所拥有的是模板管理器类,顶部有以下内容:
<#@ template language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Diagnostics" #>
<#+
public class TemplateManager
{
然后在我使用的其他t4模板中:
<#@ include file="TemplateManager.tt"#>
然后
List<Values> values = TemplateManager.PrepareVariables(code, container, itemCollection.OfType<EntityType>())
在您的情况下,ClassDefinition.tt文件将包含:
<#@ template language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Diagnostics" #>
<#+
public class ClassDefinition
{
public string NameSpace { get; set; }
public string Name { get; set; }
public string Protection { get; set; }
List<ClassProperty> Properties { get; set; }
}
#>
然后你可以加入
<#@ include file="ClassDefinition.tt"#>
答案 2 :(得分:1)
使用以下命令将C#文件包含在T4模板中:
<#@ include file="$(ProjectDir)ClassDefinition.cs" #>
将文本添加到T4模板的输出中。它不编译该类。
您在T4模板中设置了debug = true,以便在查看%TEMP%目录时可以看到T4生成的内容。运行T4模板时,您应该看到TEMP目录中生成的.cs文件。在这个文件中你将有类似的东西:
this.Write("public class ClassDefinition\r\n{\r\n public string NameSpace { get; set; }\r\n p" +
"ublic string Name { get; set; }\r\n public string Protection { get; set; }\r\n\r\n " +
" List<ClassProperty> Properties { get; set; }\r\n}");
所以C#类发生的一切就是它将在生成的T4输出中写出来。
您可能想要做的是在项目中包含ClassDefinition.cs文件,以便将其编译为项目的一部分。然后,您可以引用包含ClassDefinition类的程序集。因此,如果您的项目输出是MyLibrary.dll,其中包含已编译的ClassDefinition.cs,那么您应该可以使用:
<#@ assembly name="$(SolutionDir)$(OutDir)MyLibrary.dll" #>
应删除包含ClassDefinition.cs文件的行。
答案 3 :(得分:0)
我自己也遇到了同样的问题-我的解决方案类似于@Tehseen的解决方案,除了我将提供带有解释的实际解决方案:)
将任意C#包含到T4文件中的技巧(您希望导入的C#由T4使用,而不是简单地包含为原始文本)是隐藏* .cs文件中T4阻塞的部分-像using
指令之类的东西,并确保类型在<#+
(而不是<#
)块中声明。
这是我的解决方法:
我的“入口点” MyScript.tt
T4脚本如下:
<#@ template debug="true" hostspecific="false" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Text.RegularExpressions" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ include file="IncludedCSFile.cs" #>
<#@ output extension=".cs" #>
<#
MyClass foo = new MyClass(); // This is using a type from `IncludedCSFile.cs` in the T4 script.
#>
Hello, <#= foo.Name #>
我的IncludedCSFile.cs
如下:
// <#+ /*
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace MyNamespace
{
// */
public class MyClass
{
// etc...
}
}
// #>
// <#+ /*
//
会阻止主C#解析器(来自项目)看到T4 <#+
分隔符,这会导致项目语法错误。<#+
是 ,由T4解析器解析,并导致文件中的C#被解释为T4脚本可以使用的代码。/*
开始一个新注释,该注释使T4的C#解析器忽略using...
语句并打开namespace MyNamespace
行,否则将导致T4语法错误。
using
语句表示为<#@ import namespace="" #>
指令。// */
<#+
后面的开始块注释的分隔符。//
在项目C#编译器(看不到*/
)中隐藏了/*
,而T4的C#编译器将看到它,因为//
是被上一个/*
覆盖。
// #>
//
技巧将其隐藏在C#中,而T4仍然可以看到它。此方法有一些缺点:
//
将呈现到最终输出文件中。
*.ttinclude
文件,该文件仅具有必要的<#@ import namespace="" #>
指令,然后包含*.cs
文件。<#@ template #>
和<#@ output #>
指令,因此无法将包含的文件作为其自己的T4文件执行,据我了解,这些指令必须放在文件的开头。
*.ttinclude
文件仍然无法自行执行。答案 4 :(得分:-1)
在导入语句应该起作用后添加:
<#
ClassDefinition cd = new ClassDefinition();
#>