Utiliser les types dans un modèle T4 qui existent dans le même projet que le modèle

je travaille sur mon premier outil de génération de code T4 pour ajouter du code D'aide de procédure stocké à mon projet. J'ai créé des types personnalisés (par exemple StoredProcedure et StoredProcedureParameter pour aider avec ma génération de code et ont inclus l'assemblage et les références namespace dans mon code:

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

cela me permet d'utiliser mes types personnalisés dans mon code de modèle T4. Cependant, parce que mes types personnalisés existent dans le même projet que le code du modèle T4, Je ne peux pas recompiler mon projet une fois que j'ai lancé le modèle code sans redémarrer Visual Studio. Ce n'est pas très amusant.

j'ai lu excellent article qui résout ce problème en utilisant la boîte à outils T4, mais ça ne marche pas. Soit je suis la mise en œuvre de l' VolatileAssembly la directive de mal ou de la T4 boîte à outils n'a tout simplement pas été installé. Je ne suis pas sûr que la boîte à outils ait été installée correctement (J'utilise VS 2010 sur Win XP).

Quels sont les moyens que je pourrais être capable de résoudre ce problème?

20
demandé sur Ben McCormack 2010-08-04 21:37:28

3 réponses

Vous devez supprimer le précédent assembly référence et ajouter VolatileAssembly de référence. Si vous ne retirez pas le assembly référence tout d'abord, vous obtiendrez une erreur qu'il a déjà été ajoutée lorsque vous ajoutez l' VolatileAssembly de référence.

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

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

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

vous pouvez maintenant continuer à construire votre projet et utiliser les types définis dans ce projet dans vos modèles T4.

10
répondu Ben McCormack 2010-08-04 19:20:36

espérons que ce soit utile, il montre un cas d'utilisation de la consommation du volatileAssembly, Je n'ai pas de chance d'obtenir ce modèle de t4 à travailler à tous, mais je pense qu'il peut être utile:

// <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

1
répondu Maslow 2010-11-10 15:20:40

Vous pouvez aussi parcourir le code en utilisant 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);
    #>

j'ai posté encore plus de code en utilisant ceci comme base à http://imaginarydevelopment.blogspot.com/2010/11/static-reflection-or-t4-with-envdte.html

1
répondu Maslow 2010-11-10 21:25:24