Injection parameter conversion
DIコンテナ(on.NET)におけるコンストラクタやプロパティ、メソッドのパラメタを使ってインジェクションする場合に設定ファイルでの指定をより柔軟に行えないかなぁと考えているのです。例えば以下のようなインタフェースがあったとします。
public interface IMaximumSizable { System.Drawing.Size Maximumsize { get; set; } }
このプロパティMaximumsizeをインジェクションしたい訳ですがコードでなら簡単なSize型も設定ファイルで別なコンポーネント定義を行わないと指定することができません。
maximumsize 200 100
これが真っ当な書き方ですけれどこのような定義が多くなってくると設定ファイルも結構なボリュームになってくることが予想されます。
.NET Frameworkは元々型のコンバータが充実しており比較的簡単に利用できます。従って事前にプロパティの型が判明していればTypeDescriptorを介してコンバータの実装を取得することができます。コンバータが取得できたならばあとはインジェクションしようとしているパラメタの値が適切な型に変換が可能どうかを判定し、可能であれば変換した結果をインジェクションに使えるのではないかと思い以下のようなメソッドを用意してみました。
public static object ConvertTypeFromValue(Type parameterType, object value) { if (parameterType.Equals(value.GetType())) return value; TypeConverter converter = TypeDescriptor.GetConverter(parameterType); if (converter != null) { if (converter.CanConvertFrom(value.GetType())) { return converter.ConvertFrom(value); } } return value; } (注 .NET2.0(β2)で試してます)
そして実際にパラメタを注入する際にこのメソッドを呼ぶ訳です。(例ではプロパティをセットするためPropertyInfoとコンポーネント、注入する対象の値を引数にとっています)
public void SetPropertyValue(PropertyInfo propertyInfo, object component, object propertyValue) { try { //変換可能な値だったらコンバータを使用して変換 object value = ConvertTypeFromValue(propertyInfo.PropertyType, ropertyValue); propertyInfo.SetValue(component, value, null); } catch (Exception cause) { //プロパティのセット、又は変換に失敗した時の処理 } }
とこのようなメソッドを用意しておけばコンバータに沿った形式を設定ファイルに記述することができるようになります。
例えば先程のMaximumsizeプロパティの例であれば
200, 100
と、よりシンプルに書くことができるようになります。
この例のように値型に関しては直接指定する良さがあると思うのですが型の種類によっては直接指定することで却って管理が面倒になってしまうケースもありますし最初の例のように自己記述的に、真っ当に書けば良いのでしょうがこのような書き方を用意しておけばインジェクションの為だけに存在するメソッドやプロパティ、設定ファイルの行数等を減らせるのではないかなと思った訳です。つか、私がずぼらなだけかもしれないな。