2011年6月5日日曜日

ClayFactory

Clay面白いかも!

NuGet Package of the Week #6 - Dynamic, Malleable, Enjoyable Expando Objects with Clay - Scott Hanselman

Clay - Home

ORM使ったリポジトリを使った場合、戻りの型って結構融通効きにくいじゃないですか。select対象のクラスを全部手書きするのかよ、って。だからといって無名クラスは戻せないじゃない。objectでリフレクションとか本末転倒。

なのでdynamicを使うことにするんですけど、そのためにLINQ selectの射影をdynamicにする簡単なヘルパーを用意しとくと便利ですね。

public static class ObjectToDynamicExtensions
{
  public static dynamic ToDynamic(this object obj)
  {
    dynamic model = new ExpandoObject();
    var properties = obj.GetType().GetProperties();
    foreach (var property in properties)
    {
      ((IDictionary<string, object>)model)[property.Name] = property.GetValue(obj, null);
    }
    return model;
}
}

使用例

return from person in db.People
       select new {
         FullName = person.FirstName + 
                    " " + 
                    person.LastName,
         Age = ((DateTime.Today.Year*10000 + 
               DateTime.Today.Month*100 + 
               DateTime.Today.Day) - 
               (person.Birthday.Year*10000 + 
               person.Birthday.Month*100 + 
               person.Birthday.Day))/10000
       }.ToList().ToDynamic()
       

 

使い道はこんな感じのマッピングなんですけど、ここでちょっと残念なのが、ASP.NET MVCのViewにdynamicを渡すと、ほとんどのヘルパーが機能してくれないこと。残念ですね。凹みますね。

ちゃんと型付けしとけ、っていうのはもちろんそうなんですけどね。だからScaffoldingもあるわけでして。

とは言え、柔軟な実装にしたい。単純にマッピングをしたいようなときにはClayいいかもという流れです。

dynamicをインターフェース実装のプロキシに変換してくれるみたい。そうなればもう強い型付け完了。

インターフェースは規約で判定するみたいだけど、namespaceどうするんだろ。気になる。あ、でも、Entity ModelとOutput Modelを両方共クラスにするんじゃなくて、Output Modelはインターフェースにしちゃう感じなのかな。

dynamicから特定のインターフェースに変換したくなるときって、よくあるきがしてきた!ワクワクするね!