我正在尝试为CRUD
类创建一些脚手架,并希望使用T4来帮助构建这些类。我刚刚开始并且在调用一个住在同一个项目中的类时遇到了问题。例如:
<#@ import namespace="System.Collections.Generic" #>
<#@ template language="C#" #>
<#@ output extension=".cs" #>
<#@ include file="T4Toolbox.tt" #>
using System;
using System.Data;
using System.Data.Linq;
using System.Collections.Generic;
namespace TTFileGenerator
{
<#var entityName = "TEST";#>
public class <#=entityName#>
{
<#
MyClass myClass = new MyClass();
List<string> something = myClass.GetSomething()
...
#>
}
}
错误:
编译转换:找不到类型或命名空间名称“MyClass”(您是否缺少using指令或程序集引用?)
它是同一个项目中的公共类。我可以从项目中的其他类访问它而不是T4文件。还是一个T4新手。任何方向都会受到赞赏。
答案 0 :(得分:7)
你想做的事情不会是直截了当的。
为了让T4使用一个类(即MyClass),生成器必须引用包含的程序集或完全在T4中定义的类(这是EF代码生成器所做的)。此外,您可能正在使用设计时T4(让IDE进行生成)。设计时t4生成器将保存对dll的引用,因此您将无法再次构建项目。您实际上必须关闭Visual Studio并重新启动它。 &LT;叹息&GT;
如果您决定继续第一种方法 - 我非常赞同 - 您将希望将代码分成两个程序集(实际上是3个)。一个将包含您编写的代码,如MyClass。第二个是生成的代码。
创建第三个程序集(命令行项目)并在此处使用runtime t4。这个项目可以引用你的第一个程序集(使用MyClass)并用它做任何你想做的事情,包括你在这里展示的代码!将代码生成到第二个程序集中。
在第一个项目的项目设置中,将第三个项目的命令行工具作为构建后事件调用。这也可以是第二个项目的预构建事件。
我用这种方法创建了几个成功的面向方面编程(AOP)解决方案。唉,这可能不是你所希望的答案。
如果你真的很勇敢,可以让命令行工具生成回原始项目。这将需要您编译两次。我现在不能推荐这个。
答案 1 :(得分:2)
想象一下,我会添加一些代码来帮助其他人,尽管菲利普在头上打了一针。
我不得不打破我想要调用另一个程序集的类,并使用相对路径进行程序集引用。我没有看到任何锁定(VS 2012)......如果你在转换T4模板之前做了任何更改,你只需要记住构建这个程序集:
//Reference to another project (for testing, it lives in the debug folder)
<#@ assembly name="$(SolutionDir)\MyAssembly\bin\x86\Debug\MyAssembly.dll"#>
<#
var helper = new Utilities.MyHelperClass();
#>
<#
var something = helper.GetSomething(param1, param2);
#>