【问题标题】:Is there anyway to generate Razor views (.cshtml) based on a template beside T4?是否有基于 T4 旁边的模板生成 Razor 视图(.cshtml)?
【发布时间】:2012-10-04 07:40:19
【问题描述】:

我正在开发一些代码生成器,用于基于数据库表生成模型、控制器和视图,这样我就可以创建一个 Asp.Net MVC3 网站。我现在可以使用 CodeDOM 生成模型和控制器,但是为了生成视图,我需要一些东西来制作模板,比如从 .cs 生成 .cshtml,我认为 T4 是个好主意,但我的一些同事坚持不使用 T4,是还有其他方法吗?谢谢

【问题讨论】:

  • 你的同事说 t4 有什么问题?
  • 不确定您的同事为什么不想使用 T4。这是一个非常强大的系统,而且是免费的。它带有 Visual Studio,因此没有额外的许可费用。这是使用它的巨大动力。
  • 我不太清楚,他们说写一些干净的代码有点乱,很难。
  • 它一点也不凌乱.. 它的 C# 代码包装了您想要生成的任何代码:) 我在回答中使用的模板示例。
  • @Tony - 我明白他们为什么认为这很混乱。在 T4 中,您有代码段和输出段。在 Razor 中,您有代码部分和输出部分。因此,当您使用 T4 编写 Razor 时,您是在使用代码输出代码以输出 HTML,这可能会变成一个纠结的结。我并不是说它不能完成,或者这不是最好的方法 - 只是我可以看到它们可能来自哪里。

标签: c# asp.net-mvc-3 templates code-generation


【解决方案1】:

我不确定他们为什么反对使用 T4,因为包括实体框架在内的许多代码库都使用它们。听起来你在做我刚做完的事情。我喜欢使用 Pre-Processed T4 模板,因此我能够将数据从 C# 代码输入到模板中,并以这种方式生成文件。这允许您有多个文件输出和基本参数来传递数据。

我使用它的方式是..我创建了一个类,用于收集有关数据库的所有信息..要包含或排除哪些表..然后是每个列的信息,如 pk 或 identity 可空等。我将预处理的 t4 模板插入到该信息中,该信息能够生成所有 SQL、视图、模型、控制器信息......每当数据库发生变化时......我只需运行我的控制台应用程序并重新生成它。

预处理: http://odetocode.com/Blogs/scott/archive/2011/01/03/preprocessed-t4-templates.aspx

实体框架: http://msdn.microsoft.com/en-us/data/gg558520.aspx

MVCS脚手架: http://blog.stevensanderson.com/2011/04/06/mvcscaffolding-overriding-the-t4-templates/

T4MVC: http://mvccontrib.codeplex.com/wikipage?title=T4MVC

我再次知道这无助于回答您的问题,但 T4 非常棒,我很想听听关于为什么不使用 T4 的争论。它甚至是内置的!

顺便说一句,这里有一些智能感知!:http://t4-editor.tangible-engineering.com/T4-Editor-Visual-T4-Editing.html

如果您有任何问题,请随时联系我,我喜欢 T4,我愿意回答我能回答的任何问题。

这是我用来生成我的 POCO 模型的模板示例。由于使用我的普通 c# 方法传入数据的预处理能力,已经提取了很多内容。这个模板为我创建了 55 个基于模型的模型关闭数据库中的表。

我的“SchemeCollector”使用我创建的 DatabaseInfo、TableInfo 和 ColumnInfo 类来保存我需要的所有架构。然后我还有 9 个其他 t4 模板,它们也使用 SchemaCollector 类来填充数据。

这是我用来将数据传递到模板进行生成的扩展。我有这一切设置也可以使用 XML 文件进行配置,但我只是希望它真正可重用是不必要的。

public partial class PocoGenerator
    {
        public string Namespace { get; set; }
        public string Inherit { get; set; }
        public DatabaseInfo Schema { get; set; }
        public bool Contract { get; set; }
        public string SavePath { get; set; }
    }

这是我用来调用和填充模板并保存它的方法。

static void GeneratePoco(Config config)
        {
            var template = config.Poco;
            template.Schema = config.DatabaseInfo;

            File.WriteAllText(template.SavePath, template.TransformText());

            Console.WriteLine("      - POCOs generated for " + config.DatabaseInfo.DatabaseName + " complete");
        }

这是模板

<#@ template  debug="true" hostSpecific="true" #>
<#@ output extension=".cs" #>
<#@ Assembly Name="System.Core.dll" #>
<#@ Assembly Name="System.Windows.Forms.dll" #>
<#@ import namespace="System" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Diagnostics" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Collections" #>
<#@ import namespace="System.Collections.Generic" #> 
<#@ assembly name="System.Xml.dll" #>
<#@ assembly name="System.Data.dll" #>
<#@ import namespace="System.Data" #>
<#@ import namespace="System.Data.SqlClient" #>
<#@ import namespace="CodeGenerator.Utilities" #>

using System;
using System.Runtime.Serialization;

namespace My.Models
{   <#  
        List<TableInfo> tables = Schema.Tables; 
    #>

    //#########################################################################################################
    //   This file has been generated from the tables contained in the <#= Schema.DatabaseName #> database.
    //   Changes to this file will be overwritten when the file is regenerated. Generated: <#= DateTime.Now #>
    //#########################################################################################################
    <#
    foreach (TableInfo table in tables)
    {
    #>

    [DataContract]
    public class <#= table.Name #> : IConfigTable
    {

        <#
        PushIndent("        "); 
            foreach (ColumnInfo col in table.Columns)
            {
                if(col.IsKey || col.IsIdentity)
                    WriteLine("[Key]");

                WriteLine("[DataMember]");
                if(col.IsNullable && col.Type != "string")
                    WriteLine("public " + col.Type + "? " + col.Name+ " { get; set; }");
                else
                    WriteLine("public " + col.Type + " " + col.Name+ " { get; set; }");
            }PopIndent();#>     
    }
    <# } #>
}

【讨论】:

    【解决方案2】:

    【讨论】:

      【解决方案3】:

      我们广泛使用了 Code smith,还编写了一个插件。使用 t4 虽然您可以简单地生成类然后删除模板 - 为什么反对 T4?

      【讨论】:

      • @wiktor zychla,它解决了我回答的“还有其他方法”的问题
      • 谢谢,我检查过了,对于这一步,我更多的是寻找开源和免费的东西
      • ePez。 T4 内置于 VS 我真的很想知道为什么它是不可接受的?我知道问题是什么其他方式.. 但老实说它是如此强大为什么你需要任何其他方式?
      • @Tony 会提出一个论点,因为没有可用于参数的 UI,这是我们创建插件以提供更具交互性的向导的原因之一,但某些场景显然适合 T4。
      • @Adam,这可能是一个论点,但我再次认为用例很重要。作为 .Net 开发人员,我们通常没有用于传递参数的 UI。使用预编译的 T4 模板,您可以像任何其他方法一样将参数传递给它。在我的示例中,GeneratePoco 是与模板相关的部分类。您创建您希望模板使用的参数并将它们传入。然后您使用类型和 template.TransformText() 来应用参数。所以从技术上讲,如果你想要一个 UI,你可以创建一个。
      【解决方案4】:

      当然,我使用 Razor 进行所有代码生成(以及电子邮件生成等),并使用了不错的扩展 RazorGenerator。它允许您将此扩展指定为“自定义工具”,并从您的.cshtml 输入生成一个结果 C# 类,您可以调用(并传入@model)将文本转换为您喜欢的任何输出。 (在你的情况下有点讽刺的是,这将是剃刀 => 剃刀转换)

      【讨论】:

      • 我现在运行这个razorGenerator,正如你所说它从.cshtml生成,我需要生成到.cshtml我不需要预编译视图。
      • @ePezhman,我的回答是什么让您认为您不能使用此技术生成 .cshtml 文件? (这就是我所说的“剃刀 => 剃刀转换”)
      • 我猜 razorGenerator 是用来制作预编译的 razor 视图的,我用它做了一点工作,但看不到任何获得 .cshtml 输出的选项。
      【解决方案5】:

      我们有类似的任务,我们正在创建基于带有表单定义的输入 json 文件的动态 Web 表单。编辑器指定应在表单上显示的不同控件(控件包含不同的属性、操作、验证器)。 下面我将尝试描述我们的逻辑的基本过程:

      1. 反序列化并验证 json 文件。
      2. 准备将传递给 T4 模板的数据。
      3. 根据数据生成 MVC 模型和控制器(步骤 2)。
      4. 生成其他类(例如,一些帮助程序、模型中的复杂类型)。
      5. 添加到程序集嵌入资源,如数据源等,图像等等。
      6. 编译以上所有内容。
      7. 将 dll 拖放到模型文件夹中。
      8. 重启网站。

      模型中的所有属性都有其 [UIHint] 属性和局部视图的名称。我们有大约 10 个知道如何表示每个属性的局部视图。为了支持这个逻辑,我们扩展了 ViewEngine 和 ModelMetadata 提供者。

      ViewEngine 在其他文件夹中查找视图。 ModelMetada 提供程序添加到“AdditionalValues”自定义属性。

      我们的模型视图只有一行

      @Html.EditorForModel()
      

      我们已经重写了 Object.cshtml 来处理“深度绑定”。最困难的部分是集合项目类型复杂的集合。

      【讨论】:

        猜你喜欢
        • 2011-05-25
        • 2011-09-07
        • 1970-01-01
        • 2023-03-23
        • 2013-09-18
        • 1970-01-01
        • 2010-12-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多