使用与模板位于同一项目中的T4模板中的类型

时间:2010-08-04 17:37:28

标签: c# .net vb.net code-generation t4

我正在研究我的第一个T4代码生成工具,以便为我的项目添加一些存储过程帮助程序代码。我已经创建了自定义类型(例如StoredProcedureStoredProcedureParameter来帮助我生成代码,并在我的代码中包含了程序集和命名空间引用:

<#@ template debug="false" hostspecific="false" language="VB" #>
<#@ output extension=".generated.vb" #>
<#@ assembly name="$(TargetPath)" #>
<#@ import namespace="StoredProcCodeGenerator" #>

这允许我在我的T4模板代码中使用我的自定义类型。但是,因为我的自定义类型与T4模板代码存在于同一个项目中,所以在运行模板代码而不重新启动Visual Studio时,我无法重新编译项目。这不是很有趣。

我通过使用T4工具箱阅读了great article来解决这个问题,但它无效。我正在实现VolatileAssembly指令错误或者T4工具箱根本没有安装。我不确定工具箱是否正确安装(我在Win XP上使用VS 2010)。

我可以通过哪些方法解决此问题?

3 个答案:

答案 0 :(得分:10)

您需要删除之前的assembly引用,然后添加VolatileAssembly引用。如果您不首先删除常规assembly引用,则会在添加VolatileAssembly引用时收到已添加的错误。

<#@ template debug="false" hostspecific="false" language="VB" #>
<#@ output extension=".generated.vb" #>

<德尔> <#@ assembly name="$(TargetPath)" #>

<#@ VolatileAssembly processor="T4Toolbox.VolatileAssemblyProcessor" 
    name="$(TargetPath)" #>
<#@ import namespace="StoredProcCodeGenerator" #>  

现在,您可以继续构建项目,并在T4模板中使用该项目中定义的类型。

答案 1 :(得分:1)

希望这是有用的,它显示了使用volatileAssembly的一个用例,我没有任何运气让这个t4模板工作,但我认为它可能会有所帮助:

// <autogenerated/>
// Last generated <#= DateTime.Now #>
<#@ template language="C#" hostspecific="true"#>

<#@ assembly name="System" #>

<#@ VolatileAssembly processor="T4Toolbox.VolatileAssemblyProcessor" name="bin\debug\FrameworkWpf.dll" #>
<#@ VolatileAssembly processor="T4Toolbox.VolatileAssemblyProcessor" name="bin\debug\FrameworkTestToolkit.dll" #>
<#@ VolatileAssembly processor="T4Toolbox.VolatileAssemblyProcessor" name="bin\debug\WpfAppTemplate.exe" #>

<#@ output extension=".cs" #>

<#@ import namespace="System" #>
<#@ import namespace="FrameworkTestToolkit" #>

namespace WpfAppTemplateTest {
 using System;
 using System.Reflection;
<# 
    // Add new types into the below array:
    Type[] types = new Type[] { 
 typeof(FrameworkWpf.SafeEvent),
 typeof(FrameworkWpf.Mvvm.ControllerBase),
 typeof(FrameworkTestToolkit.PrivateAccessorGeneratorTestClass),
 typeof(WpfAppTemplate.PostController),
 typeof(WpfAppTemplate.ShellController),
 };


 // Do not modify this code
 foreach (Type type in types) {
 PrivateAccessorGenerator builder = new PrivateAccessorGenerator(type, WriteLine, Error, Warning);
 builder.Generate();
 }
#>
}

来自http://blog.rees.biz/Home/unit-testing-and-private-accessors2

答案 2 :(得分:1)

您还可以使用EnvDte

来执行代码
        <#@ template language="C#" hostspecific="True" debug="True" #>
    <#@ output extension="cs" #>
    <#@ assembly name="System.Core" #>
    <#@ assembly name="System.Xml" #>
    <#@ assembly name="Microsoft.VisualStudio.Shell.Interop.8.0" #>
    <#@ assembly name="EnvDTE" #>
    <#@ assembly name="EnvDTE80" #>
    <#@ assembly name="VSLangProj" #>
    <#@ import namespace="System.Collections.Generic" #>
    <#@ import namespace="System.IO" #>
    <#@ import namespace="System.Linq" #>
    <#@ import namespace="System.Text" #>
    <#@ import namespace="System.Text.RegularExpressions" #>
    <#@ import namespace="System.Xml" #>
    <#@ import namespace="Microsoft.VisualStudio.Shell.Interop" #>
    <#@ import namespace="EnvDTE" #>
    <#@ import namespace="EnvDTE80" #>
    <#@ import namespace="Microsoft.VisualStudio.TextTemplating" #><#
    var serviceProvider = Host as IServiceProvider;
        if (serviceProvider != null) {
            Dte = serviceProvider.GetService(typeof(SDTE)) as DTE;
        }

        // Fail if we couldn't get the DTE. This can happen when trying to run in TextTransform.exe
        if (Dte == null) {
            throw new Exception("T4Generator can only execute through the Visual Studio host");
        }

        Project = GetProjectContainingT4File(Dte);

        if (Project == null) {
            Error("Could not find the VS Project containing the T4 file.");
            return"XX";
        }

        AppRoot = Path.GetDirectoryName(Project.FullName) + '\\';
        RootNamespace = Project.Properties.Item("RootNamespace").Value.ToString();

        Console.WriteLine("Starting processing");
        ProcessFileCodeModel(Project);
    #>

我在http://imaginarydevelopment.blogspot.com/2010/11/static-reflection-or-t4-with-envdte.html

上发布了更多代码作为基础
相关问题