您是否使用代码生成工具(除了那些用于生成代理的工具以及内置到 Visual Studio 的设计器)?
您生成应用程序的哪些部分?
您通常使用自己的发电机吗?如果是这样,您编写什么类型的生成器(asp 模板、coddom 等)。如果没有,您使用什么 3rd 方工具?
我目前正在处理几个不同的项目,它们都使用自定义代码生成器来处理从生成数据库结构、业务实体、DAL 和 BLL 的所有内容。我很好奇其他人对这些工具的体验。
您是否使用代码生成工具(除了那些用于生成代理的工具以及内置到 Visual Studio 的设计器)?
您生成应用程序的哪些部分?
您通常使用自己的发电机吗?如果是这样,您编写什么类型的生成器(asp 模板、coddom 等)。如果没有,您使用什么 3rd 方工具?
我目前正在处理几个不同的项目,它们都使用自定义代码生成器来处理从生成数据库结构、业务实体、DAL 和 BLL 的所有内容。我很好奇其他人对这些工具的体验。
我属于哲学阵营,认为代码生成器是“错误的”,因为它们表明了应该成为语言一部分的东西。
但是,编写代码来编写代码一直是实用程序员道德的重要组成部分,并且在实践中,如果生成的代码默认隐藏,则代码生成效果很好。无论你想成为多么纯粹的哲学,语言永远不会像你想要解决的问题那样快速发展。
想到在 Visual Studio 中构建 Windows 窗体时生成的代码。如果需要,您可以查看生成的代码,但最好不要。然而,使用 WPF 迁移到声明性语言更为优越,因为以编程方式操作声明性代码比命令式代码更干净、更可靠。
他们应该对 LINQ-To-SQL 类做同样的事情。他们需要一种声明性语言,用于仅具有属性且没有自定义行为的类。它可能会使这些实体类更容易动态化——当底层数据库模式更改时自动更改。
我们尝试使用 CodeSmith 为我们数据库中的所有表生成 .NetTiers 类,但遇到了两个问题:
.NetTiers 臃肿,生成的代码非常庞大。我认为代码生成工具使创建feep 变得太容易了。
因为模式正在积极开发和修改,我们也必须重新生成很多东西,这最终使得将所有内容都保留在源代码控制中变得非常困难,因为所有文件都在重新生成和替换。我最终不确定生成的代码是否应该在源代码管理中。
代码生成的最佳位置应该是在编译器或构建阶段,而不是设计阶段。当您在 C# 中使用匿名类型或方法时,编译器会即时生成代码。如果你在设计阶段生成代码,你会得到一大堆东西,每次底层参数改变时都必须重新生成这些东西。
并不是说我们在 .net/web 域中工作,而是来自各种自制语言的自制代码生成工具是我们开发工具链的重要组成部分。我们有两个主要的此类工具(带有语法和解析器以及正式定义),以及许多基于 m4 和 perl 等宏的次要工具。它们最终都生成纯 C,它是本机编译的。
根据我的经验,特定领域的语言是任何大型软件工作中程序员生产力的关键工具之一。如果您正在构建诸如编译器、模拟器或其他非常复杂的软件,这些软件具有许多在基本语言(通常意味着可移植的 C 和有时是 C++)中根本不支持的重复模式,那么代码生成工具就是您要走的路。我将特定领域的语言视为泛化的下一步:首先将通用计算分解为函数(或历史的子例程),然后将通用函数分解为模板或泛型(如果这样的工具可用),然后再分解将更多的通用性和重复代码转化为成熟的自定义语言。
这一切都是为了减少您实际编写的代码量,并从编程过程中删除任何形式的繁琐重复和非增值代码。一旦模式重复,应用特定领域的语言!
当我在做经典的 asp 工作时(大约在 2001 年),我开始使用自己的生成器(数据访问、存储过程等)。我慢慢转向 CodeSmith,因为它更容易处理。我仍然主要是为我的 .NET 代码生成所有数据访问层类型的东西(包括存储过程)。
几年前,我从宏代码生成(即 CodeSmith)跳到了微代码生成。
不同之处在于,使用 CodeSmith,我为我的应用程序生成了大量的代码,所有代码都是通用的,而且是一次性的。当更改模板的源(即表结构)时,这对于边缘情况和重新生成变得有问题。我还遇到过大量携带代码的情况,这些代码我没有使用,而是从我的模板生成的。所有这些方法都有效吗?也许,也许不是。进入并清理生成的代码将是一项巨大的工作(即在同一个代码库上工作一年多之后)。
相比之下,微代码生成允许我在我想要的正确场景中准确生成我需要的类。我用来执行此操作的主要工具是 ReSharper。我这样做的方法是在编写生产代码之前编写单元测试。在这种情况下,ReSharper 使用我的单元测试作为模板来自动生成生产代码的框架。那么这只是填补空白的问题。
对于数据访问,我不再生成任何东西。我发现一个好的 O/RM 取代了我用来放入数据访问层(即 NHibernate)的所有内容。鉴于此,我将永远不会编写或生成另一个数据访问层(我拒绝)。
此外,我还获得了拥有大型单元测试套件的好处,除此之外
由于 Fog Creek Software 的内部语言 Wasabi 内置了编译时代码生成器,因此我们使用它们来自动创建映射到数据库表的实体类的主体。因此,我们可以编写一个包含十几个不同属性和方法的类,而不是编写:
<ActiveRecord("Kiwi")> _
Class CKiwi
End Class
并且 CKiwi 将为 Kiwi 表的基础架构中定义的每一列具有 Load(ix As Int32)、Commit() 和字段/属性。它使我们不必拥有庞大的 O/RM 库,但仍然允许我们快速将表添加到我们的产品中。
本着编译器精神的代码生成可能很棒。以“向导”的精神进行代码生成一律被证明是一个坏主意。
我们曾经使用 CodeSmith 来生成 NHibernate hbms、实体和其他一些东西。过了一段时间,我们厌倦了这种流动,所以我们放弃了它。
T4 生成器是免费的,值得研究生成。
我们仍然使用 Castle CodeGenerator 来生成 MonoRail 链接。
我为某些任务创建了自己的工具。从长远来看,这样做很有趣,甚至可以节省时间。对于非常乏味的任务,它甚至可以节省您的理智。
自制代码生成器非常适合从包含应如何工作的示例的最终用户电子表格构建单元测试用例。
有关示例,请参阅构建测试用例的工具。
我们使用 LLBLGen 来生成我们的数据访问层。您将生成器指向您使用的数据库,选择要使用的表,然后生成所需的类。这一切都非常快速和容易。
我们有一个内部构建的代码生成器来处理数据库访问。一个人编写存储过程并在网关类中抽象出相应的方法。
我们还生成 Web 服务以正确地与 Flash 交互——即以理智的方式处理异常。
最后,我们有一个异常生成器,它消除了异常最佳实践的繁琐工作(大量的构造函数等......)
在以前的雇主中,我们有一个本地开发的 VB.NET 应用程序,可以将 XML 模式定义文件 (XSD) 转换为静态 C++ 库。这使得使用 C++ 数据类型(bool、std::string 等)变得更加容易,并且所有有趣的 XML 代码都隐藏在这些生成的类中。
我们刚开始在办公室使用 Grails。以前,我们有一组内部 JSF/Hibernate CRUD 生成脚本。
... Grails 获胜。Grails 的代码生成非常好,可以让您在大约 15 分钟内运行 CRUD 应用程序,而无需将代码实际放入代码文件中!
当然,当你想修改它时,它可以将实际代码生成到代码文件中。大多数情况下,对于常规 CRUD,您只需更改视图即可。
我用一个来生成可序列化的数据对象,这些数据对象可以跨不同的平台(windows、linux、solaris、mac、bsd 等)进行重组。这是一个内部解决方案。
我写了一个可爱的工具,在这个工具中,我为其编写了解析器的数据格式的专家可以通过 Web 表单提交他们自己的样本,查看输出,然后告诉我它是否正确。
由此,将生成一个 jUnit 测试。迷人的。
除了没有一个人愿意使用它,我也没有收集任何测试用例。
像这里的其他人一样,我们也创建了自己的代码生成器(Inon Datamanager/Viewmanager),用于数据访问、HTML 表单处理和某些业务逻辑操作。使这项工作顺利进行的关键是对其进行设计,这样您就不必触摸或查看生成的代码。
通过这种方式,它几乎确实成为了语言的一部分——语言(在我们的例子中是 Java)被扩展为包括域模型规范和视图模型,然后您只需用真实的 Java 代码填充自定义业务逻辑。
这为我们提供了与分析师和业务用户沟通的正确工具,同时仍然拥有 Java 的能力来设置底层行为的细节。
如果对优秀的 LLBLGEN 感兴趣,您还可以评估亚音速。甚至可以看看 Rob Conery 对亚音速和 t4 之间的任何重叠或相互作用的看法。
我创建了一个自定义代码生成框架,它为多种语言(如 Java Script、Action Script、Java、C# 和 Objective C)生成 Web 服务的代理类,我不使用模板或工具,只使用普通 C# 代码生成带有一些帮助类的代码, 代码生成确实可以节省很多时间,但是我觉得生成的代码应该尽量简单,不要过度使用。