8

私はかなり複雑なものをT4テンプレートに詰め込んでいます。基本的に私は次のようなものを取ります

{=foo=}その他のテキスト...

そしてそれを次のようにクラス(ビュー)に変換します:

public class MyView
{
  public string foo{get;set;}
  public string Write()
  {
    return foo+@" more text...";
  }
}

もちろん、生成されるコードはこれよりもはるかに複雑です。とにかく、T4テンプレートは現在600行を超えるコードであり、実際にはすぐに管理できなくなります。主な問題は、コードと「コンテンツ」(つまり静的コード)の混合だと思います。ただし、この問題をきれいに修正する方法はよくわかりません(もちろん、生成されたコードには影響しません)。また、T4実行エラーをテストする以外に、T4コードを単体テストするための実行可能な方法がわかりません。そしてもちろん、生成されたコードをテストするというほぼ不可能なタスクがあるようです。

T4テンプレートコードをよりクリーンにするために使用できる「モデルビュー」タイプのフレームワークまたは手法はありますか?

4

2 に答える 2

5

複雑なテンプレートを作成する際の2つの最も重要な概念は

  1. モデルとビューの分離-これは、テンプレートロジックを最小限に抑えるのに役立ちます(多くの場合、メンテナンスの問題の原因になります)。個人的には、これにはフレームワークは必要ないと思います。必要なのはそれだけです。
  2. パーシャルはあなたの友達です-私は一般的にT4を使用してモデルからスケルトンコードを生成します。特定の動作は、モデルに組み込む価値がない場合があります。多くの場合、部分的なクラスまたはメソッドを使用してその動作を実行できるようにします。

それほど重要ではありませんが素晴らしい

  1. コードを検索可能にする-コードを検索可能にするためにコードをナビゲートするためのIntelliSenseがないため、T4アドオンのどれも十分に優れているとは思えないため、T4アドオンに依存していません。ColumnプロパティNameを呼び出す代わりに、ColumnNameと呼ぶのと同じくらい簡単にすることができます。
  2. 出力に「タグ」を挿入します-出力のその部分を生成したコードを見つけやすくします。

モデル/ビューを分離する例:

<#
    // Model for Dependency Pooperties
    Model = new []
    {
        new ClassDefinition ("MyDataGrid")
            {
                P ("CultureInfo"            , "CultureInfo"),
                P ("Pen"                    , "CellBorderPen"),
                P ("IEnumerable<object>"    , "Rows"),
                C ("WColumnDefinition"      , "Columns"),
            },
    };
#>
// Include the view
<#@ include file="..\T4\DependencyProperties.ttinclude" #>

次に、ビューはモデルを反復処理し、依存関係プロパティを生成します。

次に、依存関係プロパティの動作が部分的なメソッドとして実装されます

    partial void Changed_Columns(
        ObservableCollection<WColumnDefinition> oldValue, 
        ObservableCollection<WColumnDefinition> newValue
        )
    {
        HookUpColumns(oldValue, null);
        HookUpColumns(newValue, this);            
    }

この特定の動作をモデルに組み込むと、モデルが大幅に複雑になることに注意してください。

ついに; 有能なプログラマーでさえ、メタプログラムを有能に書くには時間がかかります。維持できると思うスタイルにたどり着くまでに何度か試みましたが、品質をより速く出荷できるので、努力する価値がありました。

これがお役に立てば幸いです...

PS。T4がこれまでにエレガントであると誰もが主張することはないと思いますが、それでもそれは非常に便利です。

于 2012-10-29T19:52:01.910 に答える
1

長い旅の末、私はついに最初の単体テストをT4テンプレートにチェックインしました。基本的に、私が行ったことは、「ビュー」(実際のT4テンプレート)と「ロジック」(コードを生成するが、実際には出力せず、T4に依存しない)を抽象化することでした。

次に、これをさらに一歩進めて、大きなハックを使用して、ロジックファイルがT4の外部でコンパイルされるようにしました。これは、インテリセンスとコンパイラのエラーが機能するようにするという素晴らしい効果がありました。また、プロジェクトを参照するだけで、単体テストからロジッククラスにアクセスできます。

実行方法の詳細が必要な場合は、コード例(前/後)とサンプルの単体テストを含む記事をブログに書きました。

于 2012-11-21T03:53:42.987 に答える