Hatena::ブログ(Diary)

Kazzzの日記 このページをアンテナに追加 RSSフィード

2011-09-22

[][][][]T4 Text TemplateによるViewModelクラスの生成 その2

前回のエントリで書いた通り、T4 Text TemplateによるViewModelの生成のためのジェネレータを作成していく。

なお、テンプレート自身はViewModelGenerate.ttという名前とし、共通で使うであろう関数群はUtil.ttという別な名前のテンプレートに定義して、ViewModelGenerate.ttでincludeすることとする。

Visual Studio ソリューション情報から全てのプロジェクト情報を列挙

EnvDTE名前空間のEnvDTE.DTEインタフェースを使うことで現在のソリューション配下の全てのプロジェクトを列挙する。

  • ViewModelGenerate.tt
<#@ template language="C#" debug="true" hostspecific="true" #>
<#@ output extension="cs"#>
<#@ import namespace="System"#>
<#@ include file="Util.tt" #>
<#
    IEnumerable<Project> projects = FindAllProjects();

処理の見通しが良くなるように、共通で使う関数は別なテンプレートに格納しておく。

  • Util.tt
<#@ template language="C#" debug="true" hostspecific="true" #>
<#@ assembly name="System.Core.dll" #>
<#@ assembly name="EnvDTE" #>
<#@ import Namespace="EnvDTE" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Collections.Generic" #>
<#+ 
    public IEnumerable<Project> FindAllProjects()
    {
        EnvDTE.DTE dte = GetDTE();
        foreach (EnvDTE.Project p in dte.Solution.Projects)
        {
            yield return p;
        }
    }
    public EnvDTE.DTE GetDTE()
    {
        IServiceProvider hostServiceProvider = (IServiceProvider)Host;
        return (EnvDTE.DTE)hostServiceProvider.GetService(typeof(EnvDTE.DTE));
    }             

長くなるので取りあえずここまで。
IEnumerable<Project>にはソリューション中のプロジェクトが列挙されるので、このプロジェクト中の構成要素を調べていくことになる。

なお、Util.ttのGetDTEメソッドで使用しているHostというシンボルはこのテンプレートがクラスに変換される際にMicrosoft.VisualStudio.TextTemplating.ITextTemplatingEngineHostインタフェースとして参照することができるプロパティだが、それにはtemplateディレクティブのhostspecific属性を"true"に設定する必要がある。

2011-09-21

[][][][]T4 Text TemplateによるViewModelクラスの生成

さて、T4 Text TemplateによりJava APTとほぼ同様のことができることが解ったので、早速プロセッサ(というかジェネレータ)を作ることにしよう。

実装の手順は以下のようになるだろう。

1. Visual Studio ソリューション情報から全てのプロジェクト情報を列挙
2. 列挙したプロジェクト情報からクラスの情報を列挙
3. 列挙したクラス情報に対象のアノテーション(属性)が見つかったら、その名前空間にクラス情報生成
4. 見つかったアノテーション(属性)からプロパティアクセサを生成
5. プロパティのセッターにOnPropertyChangedメソッドを呼び出しを生成
6. 生成したしたコードを3.で対象となったプロジェクト該当のパスに保存

Visual Studioのソリューション/プロジェクト情報を取得するには、DTE( Development Tools Environment)オブジェクトアクセスする必要がある。

方法 : DTE オブジェクトおよび DTE2 オブジェクトへの参照を取得する

次回からはこのT4 Templateとその上でDTEオブジェクトを利用してコードを生成するテンプレートを書いていこう。

2011-09-20

[][][]ViewModelの自動生成を考える

以前、Androidアプリで恒常的に使用するXMLからPOJO DTOマッピングするクラスAPT(Annotation Processing Tool)を利用して自動生成するエントリを書いたことがある。

APTでテンプレートメソッドパターンを生成する その1
APTでテンプレートメソッドパターンを生成する その2
APTでテンプレートメソッドパターンを生成する その3
APTでテンプレートメソッドパターンを生成する その4

前回のエントリでも書いたがViewModelは同じような実装が多くなる、つまりはテンプレートパターン適用できるので、インフラストラクチャで可能であれば自動生成するのが好ましい。しかしJavaと違って.NET C#で同様のプリプロセッサがあるのだろうか? (私が使っていた当時は無かった)

T4 Text Template

コード生成と T4 テキスト テンプレート

T4 Text TemplateはVisual Studioで使用することができるテンプレートエンジンであり、テンプレートからテキストファイルを生成することができる。テキストファイルとあるが当然C#やVB.NETソースコードconfigやXMLファイルを生成することもできるしそのような使い方をするのが普通らしい。これならAPTと同様の用途で使えそうだ。

内部に記述できる要素としては、テンプレートエンジンに対して設定を行うディレクティブと式があり、<# 〜 #>や<#= 〜 #>で括った部分に命令や言語(C#、VB.NET)によるロジック関数(<#+ 〜 #>)を置くことが出来、ちょっと見ではRubyのERBやJava JSPのようである

MVVMでWPF/Silverlightアプリケーションを組もうという気運が高まった2009年以降、この方法に取り組んでいる素晴らしい先輩開発者の方々が既にいらっしゃるようなので、そちらを参考にしていろいろと考えてみよう。

Declarative Dependency Property Definition with T4 + DTE | Colin Eberhardt's Adventures in .NET
ViewModelのコードの自動生成機能とアイテムテンプレートを作ってみた - かずきのBlog@Hatena

2011-09-01

[][]JetBrains ReSharper 6

f:id:Kazzz:20110901190050p:image
ReSharper:: The Most Intelligent Extension for Visual Studio

いざ本格的にVisual Studioを使おうと、細かい部分でどうにもこうにも我慢が行かず、結局アップデートしてしまった。
Version 4.5以来、最新のVersion 6へのアップデート(C#限定版)で価格は$89だったが、Eclipse同様の使い勝手リファクタリング機能を実現するのだからして、全然高価だとは思わない。

Visual Studio 2010は2005と2008を経て、GUIWPFベースとなりハードウェアアクセラレーションが有効になったお陰で随分と軽くなった感じがする。なのでReSharperをインストールしても全く重くなった感じはない。