views:

45

answers:

2

I have been using CodeDom to do some code generation. It works great, but I haven't found a way to include the generated source code files in a project. I started using T4 and the T4Toolbox to generate code because it supports integration with project files.

Does anyone know if CodeDom supports this functionality too? I'd consider taking a second look at CodeDom if it only supported this one feature.

Here is an example of how I make a source code file with CodeDom:

protected void CreateSourceFile(CodeCompileUnit codeCompileUnit,
                                string fileName,
                                out string fileNameWithExtension)
{
    fileNameWithExtension = string.Format("{0}.{1}",
                                          fileName,
                                          CodeProvider.FileExtension);

    var indentedTextWriter =
        new IndentedTextWriter(new StreamWriter(fileNameWithExtension,
                                                false),
                               TabString);

    CodeProvider.GenerateCodeFromCompileUnit(codeCompileUnit,
                                             indentedTextWriter,
                                             new CodeGeneratorOptions());

    indentedTextWriter.Close();
}

That works fine but it just outputs the file to the hard drive somewhere (probably bin folder).

Here is a second example of some code I use with T4, this one specifies the output as part of the project the template is transformed in:

public class RDFSClassGenerator : Generator
{
    private readonly string rootNamespace;
    private readonly string ontologyLocation;

    public RDFSClassGenerator(
        string rootNamespace,
        string ontologyLocation)
    {
        this.rootNamespace = rootNamespace;
        this.ontologyLocation = ontologyLocation;
    }

    protected override void RunCore()
    {

        XElement ontology = XElement.Load(ontologyLocation);
        var service = new RDFSGeneratorService(ontology);

        foreach (MetaClass metaClass in service.MetaClasses)
        {
            var rdfsClassTemplate = new RDFSClassTemplate(rootNamespace, metaClass);
            rdfsClassTemplate.Output.File = "Domain/" + metaClass.Name + ".cs";
            rdfsClassTemplate.Render();
        }

    }
}

So the T4 code will output the file into the "Domain" folder of my project. But the CodeGen stuff just outputs the file on disk and doesn't update the project file.

Here is a visual:

alt text

+1  A: 

Short answer is no, but I could be wrong (ever try to prove a negative?)

Your question was a little confusing as CodeDom isn't exactly equitable with T4. T4 templates are a convenient way of generating code files the same way, for example, asp.net generates HTML files, mixing text and code that gets executed to generate a file that is then interpreted by something else (such as a compiler or a browser). CodeDom is usually used to generate assemblies at runtime rather than files, although you can do it (as you have discovered).

While T4 makes it easy to add files to the solution, you can do this with CodeDom as well. I don't believe it supports interaction with the solution directly, but you can manage this using EnvDTE, or the automation model for Visual Studio.

The problem with this is that the automation model isn't easy to work with. EnvDTE is a wrapper around COM classes, which is always fun to code against. Also, you have to be careful when attempting to get the object. The naive implementation will get the object from the first instance of Visual Studio loaded. You have to poll the Running Object Table to find the current instance. Once you have it, you must deal with searching through the dte for the location you're looking for, deal with source control, locked files, etc etc.

Working with it, you start to learn why T4 was created in the first place.

The question you have to ask yourself is, "Does CodeDom give me enough that T4 doesn't to make up for all its shortcomings?"

Will
@Will Great feedback, thank you for your answer. I sort of suspected the answer was "No" but good to have someone else confirm it. Like you mentioned T4 was designed to make life easier, I totally agree - the t4 toolbox takes it even further. I will probably continue to use T4 for code generation. As fun as it sounds, I'm not quite motivated enough to research EnvDTE, COM Interfaces, Running Object Tables, etc.. :-)
Paul Fryer
+2  A: 

Yes, it can. Here is how: http://www.olegsych.com/2009/09/t4-and-codedom-better-together/

Oleg Sych
@Oleg Thanks for the link. I'll look into that in more details soon. Good to know both code dom and t4 can be used together.
Paul Fryer