依存性を注入せよ(コンフィグインジェクション)

同名の標題を持つ前回の日記http://d.hatena.ne.jp/Kazzz/20050315では
Dependecy Injection(以後DI)のコンストラクタインジェクションとプロパティ
インジェクション(セッタインジェクション)で使用するXMLファイルの構成を考えてみた。
今回は以前に「.NETならではのインジェクション」と自ら勝手に命名してしまった
コンフィグインジェクション(ConfigInjection)で使用するXMLについても考えて見よう。

現在作成している.NETのフレームワークはサーバサイドJavaをサーバとするいわゆる
WebクライアントとしてのGUIアプリケーションがターゲットだと言うことは以前に書いた。
つまりビジネスロジック、バックエンドリソース、ファイル等は全てJava側から動的に、
又は静的に操作、取得する事になる。
そうすると必ず必要になるのはJava側に接続する為の仕組みでありその仕組みの為の
設定はハードコード等はせずに当然外部に括り出してコードとの依存性を出来る限り
分離しておく必要がある。

設定要素名をwebconnectionとし必要な属性を含んだXMLの構造は以下のようにしてみよう。


    

name属性はアプリケーション側でこの接続を識別する為に使用する"名前"であり
allowCompress属性はこの接続でやりとりするデータをGZip圧縮するか否かを決定する。
timeout属性はJava側からの応答を待つ時間の限度を指定する。
最後のurlは接続対象となるJava側のエンドポイントだ。大抵はこのエンドポイントに
接続してなんらかのデータ、コンテンツをJava側から結果として受取ることになる。
通常はこのような構造を必要なだけApp.configに定義して内部では同名のクラスを用意して
この接続を使用するクラスで参照すれば良い。
App.configは.NETで新たな構成要素を追加する場合の標準的な構造に則ってこんな感じに
なるだろう。


    
      

このような記述によりアプリケーションはwebconnectionのインスタンス
直接生成する事と各構成パラメタをハードコードする事による依存性から開放される。
この設定を使用するクラスのインスタンスコンポーネントとしてDIにより生成される
としよう。このコンポーネントコンストラクタの引数で上述したwebconnectionを
指定できるとする。
前回の日記で書いたようにDI用の設定ファイルは以下のようになる。


    con1

コンストラクタインジェクションで引数にwebconnectionの名前を指定した事によって
依存性を注入する事になる。
更にこのコンポーネントでwebconnectionを使用する時に敢えてApp.configで設定された
パラメタと違う構成で動かしたいとしよう。しかしFooComponentクラスは接続名を指定
できるだけでありwebconnectionの各パラメタを変更する事はできない。
そんな場合にApp.configで書いたwebconnectionの設定を一部変えてFooComponentに注入
できればテストの時等に非常に便利だ。こんな感じにcomponent.configが書ければ良いな。


    
        
    

が新しく追加されたXML要素でありこの要素の中でApp.configで
指定したのと同様のwebconnection記述を許すようにする。これでwebconnectionの
構成自体を注入する事になる。
もちろんDIのコンテナはこのように構成が注入された場合にはこのconfigを使用して
webconnectionクラスを構成してコンポーネントが参照できるようにする必要がある。


この例のFooComponentのように接続先があるクラスのテストを行う場合はテスト用の
エンドポイントを用意したり間にTCP/IPスニファを挟んだりする為に頻繁にurlを変えたり
圧縮を無効にしたりするんだけどそれをApp.configを書換える事ではなくDI側で
オーバライドするイメージで運用できるといいなと考えている。