CodeDom 可以将源代码文件添加到项目中吗?

发布于 2024-09-11 17:48:18 字数 2212 浏览 5 评论 0 原文

我一直在使用 CodeDom 进行一些代码生成。它工作得很好,但我还没有找到一种方法将生成的源代码文件包含在项目中。我开始使用 T4 和 T4Toolbox 生成代码,因为它支持与项目文件集成。

有谁知道 CodeDom 是否也支持此功能?如果 CodeDom 仅支持这一功能,我会考虑再考虑一下。

下面是我如何使用 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();
}

效果很好,但它只是将文件输出到硬盘驱动器的某个位置(可能是 bin 文件夹)。

这是我与 T4 一起使用的一些代码的第二个示例,该示例将输出指定为转换模板的项目的一部分:

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();
        }

    }
}

因此,T4 代码会将文件输出到我的项目的“Domain”文件夹中。但 CodeGen 的东西只是将文件输出到磁盘上,并不更新项目文件。

这是一个视觉效果:

alt text

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

你不是我要的菜∠ 2024-09-18 17:48:18

简短的回答是否定的,但我可能是错的(曾经尝试证明是否定的?)

您的问题有点令人困惑,因为 CodeDom 与 T4 并不完全相等。 T4 模板是一种以相同方式生成代码文件的便捷方法,例如,asp.net 生成 HTML 文件,混合文本和执行的代码以生成文件,然后由其他东西(例如编译器或浏览器)解释)。 CodeDom 通常用于在运行时生成程序集而不是文件,尽管您可以这样做(正如您所发现的)。

虽然 T4 可以轻松地将文件添加到解决方案中,但您也可以使用 CodeDom 来完成此操作。我不认为它支持直接与解决方案交互,但您可以使用 EnvDTE 或 Visual Studio 的自动化模型来管理它。

问题是自动化模型不容易使用。 EnvDTE 是 COM 类的包装器,针对它进行编码总是很有趣。另外,尝试获取该对象时必须小心。简单的实现将从加载的 Visual Studio 的第一个实例中获取对象。您必须轮询 运行对象表来查找当前实例。拥有它后,您必须在 dte 中搜索您要查找的位置,处理源代码控制、锁定文件等。

通过使用它,您将开始了解最初创建 T4 的原因。

您必须问自己的问题是:“CodeDom 是否给了我足够的 T4 无法弥补的所有缺点?”

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?"

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文