DIのデバッグ

周知だが去年からDI(Dependency Injection)ベース(既にDI部分は設定ファイルの語彙がs2dotnetと同じなので敬意を表して"+Sesar2クローン"、"+s2dotnetクローン"と呼ぶべきなのかもしれない)のスマートクライアント向けフレームワークを書いている。テスト目的で書いたGUIアプリケーションで使用しているコンポーネントを可能な限りDIにより構成してみようと思い設定ファイルを書いてみたのだが中々凄いボリュームとなった。(約300行)

(※画像は大人の事情により故意にぼかしてあるのであしからず)
実際のアプリケーションの開発ではこのような大量の設定ファイルを書くべきではないし何がコンポーネントなのかをきちんと設計しDIコンテナに制御させる対象を絞る、設定ファイルを階層化して役割毎に複数に分ける、等の対策を嵩じるべきなのは当然であるが実際にこのように大量の設定ファイルを書いてそれぞれのコンポーネントDIコンテナによりどのように依存性を注入されているかを検証するのは必要だしかなりやっかいである。特にSesar2アーキテクチャDIコンテナは依存性のオートバインディング(ずっとバインディングだと思っていたのだがオートワイヤリングとも言うらしいどっちがそれっぽいんだろう)がデフォルトで機能するので気をつけないと知らない間にちゃっかりとプロパティがセットされてしまったりするので混乱度合が更に上がる。
このような場合、クラシックな手段だがやはり履歴を採取するのが一番だ。インジェクションの種類をプロパティ(.NETだからね)に絞って考えてみると

コンポーネント( 名前、型(クラス)、スコープ(シングルトン、プロトタイプ、etc.)
・プロパティ( 名前、型、バインドされた値、自動バインドか手動かの区別 )

これらの情報をDIコンテナ内でコンポーネントアセンブルされる際に整形してデバッグ出力等に出力してやるだけで依存性がどのようにDIコンテナ内部で解決されているかがかなり解りやすくなる。

採取されたDI履歴のログイメージ

######################################## begin #######################################
  Component = [name = , Type = Framework.ComponentImpl
    Property = Name, Type = System.String, value = "", manualbinding
    Property = Connection , Type = IConnection value = [ Component = [name=, Type = ConnectionImpl 〜], autobinding
    Property = Table, Type = System.String, value = テーブル名, manualbinding
    Property = Key, Type = System.String, value = キー, manualbinding
  ]
######################################## end   #######################################

むろんTDDをベースに全ての組み合わせをテストとして書くのはやぶさかではないがそのような開発フェーズに渡る前にいろいろと検証したいこともあるし、DIコンテナに慣れていないプログラマはまず間違いなく設定ファイルの記述に戸惑い記述ミスを発生すると思われるので慣れるまではこのように実際に設定ファイルに記述したコンポーネントがどのように組みたてられているかを見ることは重要だと思う。(なのでこの機能は簡単にOn/Offできることが望ましい)