代码之家  ›  专栏  ›  技术社区  ›  Ben McCormack

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

  •  21
  • Ben McCormack  · 技术社区  · 16 年前

    我正在开发我的第一个T4代码生成工具,将一些存储过程帮助程序代码添加到我的项目中。我已经创建了自定义类型(例如。 StoredProcedure 和 StoredProcedureParameter 要帮助生成代码并在代码中包含程序集和命名空间引用,请执行以下操作:

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

    我读了一本书 great article 通过使用T4工具箱解决了这个确切的问题,但它不起作用。要么我在实施 VolatileAssembly 指令错误或T4工具箱根本没有安装。我不确定工具箱是否安装正确(我在WinXP上使用VS2010)。

    有哪些方法可以解决此问题?

    3 回复  |  直到 15 年前
        1
  •  10
  •   Ben McCormack    16 年前

    您需要删除上一个 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" #>  
    

        2
  •  1
  •   Maslow    15 年前

    希望这是有帮助的,它显示了一个使用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

        3
  •  1
  •   Maslow    15 年前

    您还可以使用 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