5

Asp.Net MVC3 Webサイトを作成できるように、データベーステーブルに基づいてモデル、コントローラー、およびビューを生成するためのコードジェネレーターを開発しています。今はCodeDOMでモデルとコントローラーを生成できますが、ビューを生成するには、.csから.cshtmlを生成するなど、テンプレートを作成するための何かが必要です。T4は良いアイデアだと思いましたが、同僚の中にはT4を使用しないことを主張する人もいます。他に方法はありますか?ありがとう

4

5 に答える 5

6

Entity Frameworkを含む多くのコードライブラリがT4を使用しているため、なぜT4の使用に反対するのかわかりません。あなたは私がやったばかりのことをしているようですね。前処理されたT4テンプレートを使用するのが好きだったので、C#コードからそれらにデータをフィードし、その方法でファイルを生成することができます。これにより、複数のファイルを出力し、基本的にデータを渡すためのパラメーターを設定できます。

私の使い方は..データベースに関するすべての情報を収集するために使用されるクラスを作成しました..どのテーブルを含めるか除外するか..次に、pkやidentitynullableなどの各列に関する情報を作成しました。前処理したt4テンプレートをプラグインすると、その情報ですべてのSQL、ビュー、モデル、コントローラー情報を生成できました。データベースが変更されるたびに、コンソールアプリを実行して、すべてを再生成しました。

前処理済み:http : //odetocode.com/Blogs/scott/archive/2011/01/03/preprocessed-t4-templates.aspx

エンティティフレームワーク:http: //msdn.microsoft.com/en-us/data/gg558520.aspx

MVCScaffolding: 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クラスを使用しています。次に、SchemaCollectorクラスを使用してデータを設定する他の9つのt4テンプレートがあります。

これは、生成のためにデータをテンプレートに渡すために使用する拡張機能です。構成にも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();#>     
    }
    <# } #>
}
于 2012-10-16T14:13:26.887 に答える
2

あなたの答えはここにあります:https ://stackoverflow.com/a/2457206/538387

ASP.NETMVCと仮想ビューへのリンクがあります

于 2012-10-21T01:18:30.570 に答える
0

コードスミスを多用し、プラグインも作成しました。t4を使用すると、クラスを生成してからテンプレートを削除することができますが、なぜT4に反対するのでしょうか。

于 2012-10-13T21:13:37.103 に答える
0

確かに、私は素晴らしい拡張機能RazorGeneratorを使用して、すべてのコード生成(および電子メール生成など)にRazorを使用しています。これにより、この拡張機能を「カスタムツール」として指定し、入力から結果のC#クラスを生成して、テキストを任意の出力に変換する.cshtmlために呼び出す(および渡す)ことができます。@model(皮肉なことに、あなたの場合は、かみそり=>かみそりの変換になります)

于 2012-10-14T00:26:55.507 に答える
0

同様のタスクがあり、フォーム定義を使用して入力jsonファイルに基づく動的Webフォームを作成しています。エディタは、フォームに表示する必要のあるさまざまなコントロールを指定します(コントロールにはさまざまなプロパティ、アクション、バリデーターが含まれます)。以下では、ロジックの基本的な手順について説明します。

  1. jsonファイルを非認証化して検証します。
  2. T4テンプレートに渡されるデータを準備します。
  3. データからMVCモデルとコントローラーを生成します(ステップ2)。
  4. 追加のクラスを生成します(たとえば、一部のヘルパー、モデルからの複合型)。
  5. dataSourcesなどの埋め込みリソースをアセンブリに追加し、画像を何でも追加します。
  6. 上記のすべてのものをコンパイルします。
  7. モデルフォルダにdllをドロップします。
  8. サイトを再起動します。

モデル内のすべてのプロパティには、部分ビューの名前を持つ[UIHint]属性があります。各プロパティを表す方法を知っている約10の部分ビューがあります。このロジックをサポートするために、ViewEngineおよびModelMetadataプロバイダーを拡張します。

ViewEngineは、追加のフォルダーでビューを検索します。ModelMetadaプロバイダーは、「AdditionalValues」カスタムプロパティに追加します。

モデルのビューには1つの行があります

@Html.EditorForModel()

'ディープバインディング'を処理するためにObject.cshtmlをオーバーライドしました。最も難しかったのは、コレクションアイテムが複雑なタイプのコレクションでした。

于 2012-10-17T17:35:17.243 に答える