評価式と型指定
またまた久しいDIネタ。最近DIネタを扱う機会が減っているが、これは拙作のリッチクライアント(スマートクライアント)用のフレームワークに組み込まれて、既に実際の開発で使っているためにバグFIXがメインになっているためであり、決して使わなくなってしまった訳ではないので念のため。実際には使わないどころか、無いとお話にならない状況になりつつある。
DIコンテナのインジェクションにおける評価式の書き方や活用方法に関しては、過去にいろいろと採りあげてきた経緯がある。
最終的に開発でのデフォルトはNullExpression、つまりはスクリプトの式評価エンジンを使わずにインジェクションを行う方法であり、式評価を使った方が判りやすい場合のみ、JavascriptExpression(Javascript評価式)をXML要素として挿入することで、好みの式評価スクリプトエンジンを切り替えて、プロパティや引数パラメタのインジェクションを行うことを可能にしている。(IExpressionインタフェースのヌル実装)
例)
NullExpression(式評価無し)
2006/11/7 06:30
JavascriptExpression(Javascript式評価)
DataTime.Now
NullExpressionは、DIコンテナ上に既に登録されているコンポーネント"以外"は、.NETの型(値型、Enum、参照型)、又は型コンバータによりオブジェクトが評価される。これにより"より軽い"インジェクションが行われるのだが、以下のようにコンストラクタ、又はメソッドインジェクションとして引数パラメタをインジェクションするケースでは問題が発生する。
1000 2000
このように引数が二つあり、それぞれ1000と2000がセットされているとしよう。プロパティインジェクションであれば、リフレクションにより、予めプロパティの型情報を調べることで.NET型変換を実施することが可能だが、コンストラクタの場合、同じ手は使えない。なぜならばコンストラクタの引数の型は予め取得することはできないからだ。
上記のように記述されたパラメタの並びに対応するコンストラクタを探すには、
1. 必要な引数の個数が等しいコンストラクタ
2. 尚且つ、それぞれの引数が代入可能なコンストラクタ
これらの条件を満たしている必要があるのだが、ここで大きな問題がある。それは、引数の個数が同一なコンストラクタのオーバロードが複数ある場合、引数が代入可能かを調べるためには、引数がインジェクションされる際の型が必要なのである。これでは堂々巡りだ。さて、どうしたものか。