在Visual Studio项目中包括自定义生成的代码文件 [英] Including custom generated code files in Visual Studio project

查看:95
本文介绍了在Visual Studio项目中包括自定义生成的代码文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究代码生成器,以从XML定义生成数百个c#类定义文件.我正在直接编写.cs文件;我没有使用T4. (我真的需要学习这个.)
我的问题是:
如何将生成的文件包含在要编译的Visual Studio项目中?

[添加说明:]
生成的代码将在现有项目中使用(例如EntityFramework .edmx之后的.Designer.cs文件).
这些类将在本项目的其余部分中使用.
可以手工生成文件,但要生成的文件太多(数百个!),这将非常繁琐且容易出错.
仅当XML文件更改时,才需要重新生成它们.除非我在XML(或生成的代码)中发现错误,否则这是一个低概率.
我不需要动态加载.

到目前为止,我只是通过基于XML文件中信息的类定义的变化,将暴力文本编写到.cs文件中.
(这是快速的方法, vs.学习T4.我也考虑过CodeDOM,但是文本输出不需要学习曲线.)

(而且,现在它正在为每个类生成一个.cs文件,但是如果可以更轻松地钩住"现有的,它也可以为所有内容轻松生成一个 big .cs文件.

I''m working on a code generator to generate several hundred c# class definition files from XML definitions. I''m writing the .cs files directly; I''m not using T4. (I really need to learn this.)
My question is:
How do I get the generated files to be included in the Visual Studio project to be compiled?

[Adding clarification:]
The generated code will be used in an existing project (like the .Designer.cs file behind the EntityFramework .edmx).
These classes will be used within the rest of this project.
I could have hand-generated the files but with so many (hundreds!), that would have been extremely tedious and error prone.
They will only need to be regenerated if the XML file changes. This is a low probablility, unless I discover an error in the XML (or generated code).
I don''t need dynamic loading.

So far I''ve just been brute-force writing text to .cs files with the variations in the class definitions based on the info in the XML file.
(That was the quick way to go, vs. learning T4. I also thought about CodeDOM, but text output didn''t require the learning curve.)

(Also, right now it is generating a .cs file for each class, but it could just as easily generate one big .cs file for everything, if that makes it easier to "hook into" the existing project.)

推荐答案

作为实验",我将代码生成器的2个部分转换为2个T4文本模板.
(从编程方式编写代码转换为使用T4模板要容易得多.但是,如果没有更多经验,直接构建模板似乎仍然会更加困难...没有IntelliSense,没有编辑器语法错误检查等) .)

这些文件可以直接正确集成到内部版本中.
但是,它们是硬编码"到源XML文件的,因此Visual Studio仍然不知道应该在每个版本上都重新生成它们(就像Entity一样;实际上Entity甚至会重新生成.Designer.cs文件.手动编辑!)

我可能仍然会看一下CodeDOM,但是,如果可以更安全"地再生,这似乎是一个很好的解决方案.
As an "experiment" I took 2 parts of my code generator and converted them to 2 T4 Text Templates.
(Converting from programmatically writing the code to using the T4 template is much easier than I expected. Without more experience, though, directly building the template seems like it would still be more difficult...no IntelliSense, no editor syntax error checking, etc.)

These files integrated directly into the build correctly.
However, they are "hard coded" to the source XML file, so Visual Studio still doesn''t know that they should be regenerated on every build (like Entity does; actually Entity will even regenerate the .Designer.cs file if it is manually edited!)

I may still look at CodeDOM, but this seems to be a pretty good solution, if I can get "safer" regeneration.


我认为最好的方法是使用Visual Studio API,看看扩展Visual Basic和Visual C#项目 [
I think the best way is to use the Visual Studio API, have a look at Extending Visual Basic and Visual C# Projects[^]

Best regards
Espen Harlinn


可能,此问题不应与Visual Studio捆绑在一起.我的意思是,您当然可以生成一个项目文件,.NET甚至为您提供了使用它的综合API.但是,最有可能的是,您应该将您的体系结构基于CodeDOM:
http://msdn.microsoft.com/en-us/library/650ax5cx.aspx [ ^ ].

背景知识:开发所需的一切实际上都与.NET Framework捆绑在一起,这是一个免费重新分发的东西.至少,您始终拥有C#,VB.NET编译器,MSBuild和所有使用它们的组件.就是说,安装.NET的用户始终可以使用应用程序在运行时编译和加载的程序集.为此,绝对不需要Visual Studio.这样,您的可能性可能比您预期的要好. FCL(框架类库)始终为您提供这些语言的 CodeDOM提供程序可以用来生成临时存储的程序集,这些程序集可以永久重复使用.

您还需要能够理解和使用反射:
http://msdn.microsoft.com/en-us/library/hh156524.aspx [ ^ ],
http://msdn.microsoft.com/en-us/library/f7ykdhsy.aspx [ ^ ].

为此,请不要认为反射太慢.是的,它很慢,但是如果设计正确,它的运行时使用将减少到最低限度.最佳地,您可以开发一些静态绑定的接口.当动态生成装配时,仅需要反射来定位实现接口的某种类型,实例化它(在通过接口引用可访问的类型/结构的实例中获取),然后完成反射部分.当获得表示实现类型的接口引用时,只需使用此接口,并通过接口成员,就可以访问动态生成的程序集中的所有其他类型.

请查看我过去在相关主题上的答案,但请记住,在某些答案中,我讨论了比您可能需要的高级得多的问题,主要涉及应用程序域以及使用IPC在各个域中工作的需要.您可能不需要它,所以首先关注CodeDOM的用法:
创建使用可重载插件的WPF应用程序... [^ ],
AppDomain拒绝加载程序集 [使用CodeDom生成代码 [在现有实例上的C#反射InvokeMember [通过程序集的字符串表示形式收集程序集类型 [ ^ ].

欢迎您提出后续问题.

祝你好运,
—SA
Probably, this problem should not be tied with Visual Studio. I mean, of course you can generate a project file and .NET even gives you a comprehensive API for using it. But, most likely, you should rather base your architecture on CodeDOM:
http://msdn.microsoft.com/en-us/library/650ax5cx.aspx[^].

Some background: everything you need for the development is actually bundled with .NET Framework, a freely redistributed thing. At least, you always have C#, VB.NET compiler, MSBuild and all the components to use them. That said, the user who installed .NET can always use assemblies compiled and loaded during run time by your application. Visual Studio is absolutely not needed for this purpose. This way, your possibilities are probably even better then you expected. The FCL (Framework Class Library) always provides you with the CodeDOM providers for these languages which you can use to generate assemblies, either temporary, of stored re-used permanently.

You also need to be able to understand and use Reflection:
http://msdn.microsoft.com/en-us/library/hh156524.aspx[^],
http://msdn.microsoft.com/en-us/library/f7ykdhsy.aspx[^].

Don''t think that Reflection is too slow for this purpose. Yes, it is slow, but if you design things properly, its runtime use is reduced to minimum. Optimally, you can develop some statically bound interface(s). When you generate an assembly dynamically, Reflection is only needed to locate some type implementing the interface, instantiate it (get in in instance of a type/structure accessible through the interface reference), and you are done with Reflection part. When you got an interface reference representing the implementation type, you just use this interface, and through the interface members, you might access all other types in the dynamically generated assembly.

Please see my past answers on related topics, but keep in mind, that in some of those answers I discuss much more advanced matter than you might need, mostly related to Application Domains and a need of using IPC to work across the domains. You might not need it, so first focus on CodeDOM usage:
Create WPF Application that uses Reloadable Plugins...[^],
AppDomain refuses to load an assembly[^],
code generating using CodeDom[^],
C# Reflection InvokeMember on existing instance[^],
Gathering types from assemblies by it''s string representation[^].

Your follow-up questions are welcome.

Good luck,
—SA


这篇关于在Visual Studio项目中包括自定义生成的代码文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆