メタプログラミング

T4(テキスト・テンプレート)

.netでは、T4(Text Template Transformation Toolkit)を使うことで、メタプログラミングができます。
T4はVisual Studioに統合されているので、簡単に使うことができます。
「追加」→「新しい項目」→「テキストテンプレート」を選択すると、拡張子が 「tt」のファイルができます。

このTextTemplate1.ttにテンプレートとなるテキストブロックと制御ブロックを埋め込むことで実装します。

制御ブロックの例
・template:言語の指定
 例)<#@ template language="cs" #>
・output:出力ファイルの拡張子
 例)<#@ output extention=".g.cs" #>
・assembly :アセンブリの参照
 例)<#@ assembly name="System" #>

制御ブロック内にコードを埋め込む場合は、<# #> や <#= #> の制御ブロックを使用します。

簡単な例として、Excelなどで記述されたテーブル定義からクラスを生成するテンプレートを作ってみます。

テーブル定義
取引先マスタ, TorihikisakiMst
取引先コード, TorihikisakiCode
取引先名, TorihikisakiName
…(大量に列が続く)

<#
// 制御ブロック
var CSVデータ =  定義ファイルの読み込み();
#>

//テキストブロック
class <#= CSVデータ.テーブル名 #>Entity
{
   <#
   // 制御ブロック
   foreach( var 列名 in CSVデータ.列名リスト)
   {
   #>
       public string <#= 列名 #> {get; set;}
   <#
   }
   #>
}

適当な擬似コードですが、このテンプレートから生成されるコードは次のようになります。

//テキストブロック
class TorihikisakiMstEntity
{
public string TorihikisakiCode {get;set;}
public string TorihikisakiName {get;set;}
}

PushIndent()やPopIndent()を使えば、もう少し整形して出力することもできます。

この例は簡単過ぎてありがたみはありません。1つのテーブル定義から複数のクラスが必要になる場合などは転記ミスが減るので、ケアレスミスによるバグを防げます。

今の会社のプロダクトではテーブル定義1つにつき、最低4つのクラスが必要だったりします。

テンプレートが出来上がると、自動でソースができあがる様子を見るのは面白いです。ただ、通常のプログラミングとはかなり異なるので、エラーが出たときの対応が大変になります。

実際のプロダクトに取り込むとメンテナンスできる人が限られてしまうため、中々採用されにくい手法だとは思います。

ASP.net MVC や EntityFrameworkでも使われてるみたいです。

この記事が気に入ったらサポートをしてみませんか?