[わんくま同盟 名古屋勉強会] 第4回 ソースコードの解説
※ 「DI コンテナの本懐 ~ IoC の実装も楽々!」 の資料とソースコードは、 こちら → わんくま同盟 勉強会の資料
◆ 前提条件
- C# 2008 ( Express Edition で OK のはず )
- Unity Application Block 1.1
※ Unity Application Block 自体は C# 2005 / VB 2005 から利用可能です。
◆ このサンプルコードはなにか?
DI コンテナである Unity Application Block を使って、 3つのアセンブリを組み上げて動かしてみるサンプルです。
- ApplicationStarter プロジェクト
UI コンテナを使って、 3つのアセンブリを組み上げて動かす役割。 全てのアセンブリを知っている 「神様」 モジュールです。 これが exe になり、 残りのプロジェクトは dll です。
※ 設計の話題として、 「神様」 モジュールにイロイロやらせてしまうと、 結局グローバルで複雑なコードが出来上がってしまうので、 よろしくないとされています。 アプリケーションを組み立てて、 スタートメソッドを蹴飛ばしたらお仕舞い、 という程度のシンプルなものに留めておくべきでしょう。 - ApplicationStarter2 プロジェクト
( 後述 ) - BL プロジェクト
Business Logic です。 アプリケーションのキモの部分。
※ 今回は、 このビジネスロジックが、 他のブロックよりも安定していて変わりにくい部分である、 という仮定で話を進めています。 - SqlAcc プロジェクト
SQL Server Accessor です。 このサンプルでは実装してないのですが、 SQL Server にアクセスする役割を持たせてある、 と思ってやってください。 - XmlAcc プロジェクト
XML file Accessor です。 このサンプルでは実装してないのですが、 XML のファイルにアクセスする役割を持たせてある、 と思ってやってください。 ApplicationStarter2 プロジェクトで使っています。 - UIwpf プロジェクト
WPF による UI ( User Interface ) です。 このサンプルでは実装してないのですが、 ボタンをクリックされたら、 テキストボックスに入力されている文字列を使って、 BL にリクエストを出し、 返ってきた結果をデータグリッドかなんかに表示する、 というような実装がしてあると思ってやってください。
◆ 注目すべきところは?
- 各プロジェクトの参照設定
とくに、 BL が他のプロジェクトを参照していないところ。
このことは、 ロジックは画面にもデータアクセスにも依存していなくて、 独立した存在になっていることを示しています。 裏を返せば、 インターフェースさえ合えば、 どんな画面でもデータアクセスでも、 くっつけられるということです。 - 制御が反転しているところ
BL プロジェクトと SqlAcc プロジェクトの関係
モジュール間の依存方向: SqlAcc → BL
メソッド呼び出しの方向: BL → SqlAcc
また、 SqlAcc のインターフェースである IDataFinder の定義も、 BL 側にあります。 - Dependency 属性
DIContainerSample.BL.Users の UserDataFinder プロパティには、 Dependency 属性が付いています。 Unity Application Block のコンテナは、 この属性を認識して、 そのプロパティの型に一致するインスタンスを、 自動的にセットしてくれます。 - UnityContainer
UnityContainer は、 Unity Application Block のコンテナです。 DIContainerSample.ApplicationStarter.Builder クラスの Main() メソッドで、 アプリケーションの組み立てをやっています。
UnityContainer のインスタンスを作り、 RegisterType() メソッドで、 インターフェースとそのインターフェースに使う実装クラスを、 コンテナに教えます。 コンテナの Resolve() メソッドを呼び出すと、 教えられたインターフェースの実装をインスタンス化し、 Dependency 属性の付いたプロパティに当てはめてくれます。
◆ セッター・インジェクションとコンストラクタ・インジェクション
Dependency 属性の付いたプロパティにインスタンスを当てはめるのを、 セッター・インジェクション ( Setter Injection ) と呼びます。
インジェクションの方式にはその他に数種類ありますが、 そのうちのコンストラクタ・インジェクション ( Constructor Injection ) も、 使ってあります。
DIContainerSample.UIwpf.Runner クラスのコンストラクタは、 引数付きです。 Unity Application Block は、 引数付きコンストラクタを見つけると、 その引数に渡すオブジェクトを自動的に用意してくれます。
※ セッター・インジェクションであれコンストラクタ・インジェクションであれ、 そこに渡すオブジェクトの型 ( インターフェース ) と実装クラスが何であるかを、 コンテナが知っていなければインジェクトできませんよね。 それを教えてあげるためのメソッドが、 RegisterType() です。
※ あとからムリヤリ使ったので、 わざとらしいです。 f(^^;
というか、 それで不要になった Window1.xaml.cs の Dependency 属性を消し忘れてるし… orz
◆ XML ファイルで依存関係を指定する
Unity Application Block は、 Resolve() メソッドの代わりに、 XML ファイルで依存関係を記述することもできます。
- ApplicationStarter2 プロジェクトは、 その方法で組み立てるようになっています。
依存関係の記述は App.config に書いてあります。 - container 要素
どのインターフェース ( type 属性 ) に、 どの実装を結びつける ( maptTo 属性 ) か、 という記述が入っています。 基本的には、 この要素だけ書けば良いみたいです。 - typeAlias 要素
type 属性などを直接記述すると、 "名前空間.型, アセンブリ名" という長い記述になります。 それでは読みにくいので、 typeAlias で別名を定義できます。
| 固定リンク
「プログラミング」カテゴリの記事
- 【.NET / Win8.1 ストアアプリ】 HttpClient で TLS 1.1 / 1.2 に対応するには(2018.06.17)
- 【VS2017 15.7pv2】 XAML のランタイム ツールに 「ヒートマップ」 が増えた(2018.03.28)
- 【.NET Core】 プロジェクトを作ると 「project.assets.json が見つかりません」 エラー(2018.02.10)
- 【#UWP】 ビットマップの表示色を変える (Win2D.uwp 経由で Direct2D を使う)(2017.08.23)
- 【#UWP】 CompactOverlay モード: Picture in Picture というか、「最前面に表示」するウィンドウを作る(2017.08.16)
「-プログラミング ( わんくま )」カテゴリの記事
- [わんくま名古屋] 第21回: Metro サンプルコード解説 (1/3)(2012.04.15)
- [わんくま名古屋] 第21回は 4月 14日 - Windows 8 Metro をやるよ~♪(2012.04.12)
- [わんくま東京] 第59回の資料を公開しました(2011.06.02)
- [わんくま東京] 第59回は 5月 28日 - 名古屋から侵略します♪(2011.05.23)
- [わんくま名古屋] 第17回は 4月 9日 - TDD ネタで喋ります(2011.04.03)
この記事へのコメントは終了しました。
コメント
思い出した。
当夜本番で、 たしか中さんから突っ込まれたんだけど。
突っ込まれた通りで、 DI コンテナだとか、 それを XML で記述するだとかは、 しっかり古い技術です。
Java の世界では、 もう何年も前から、 当たり前になってて。 .NET の世界には、 去年くらいからかな、 よーやくやってきた、 ってところ。
投稿: biac | 2008年10月28日 (火) 09時49分
> DIだと遅くならない?
起動時に、 コンテナが挿入するとことソコに嵌るモノを探し出して組み立てる時間は、 余計に掛るでしょうねぇ。
組上がってしまえば、 Unity ではオブジェクト間の呼び出しにプロキシが噛んでたりするわけじゃないんで、 動作が遅くなったりはしないと思いますよ。
投稿: biac | 2008年10月28日 (火) 08時30分
あ~その方には流れてなかったですよw>操
パフォーマンスの話題になってました。
(DIだと遅くならない?ってところから)
投稿: D | 2008年10月28日 (火) 01時35分
そーいえば。
「BLって、 Boys L(ry」 って突っ込みが、 会場からは無かったよーな気がするんですけど。 見えてなかった MISAO チャットでは、 出てたのかな? f(^^;
投稿: biac | 2008年10月27日 (月) 01時24分
> BusinessLogicが一切参照を持たない実装はかなり魅力です。
面白いでしょう? (^^;
このサンプルでは、 インターフェースの定義を全部 BL に持ってきてみたのですが。
定義が一箇所に集まるのはいいのだけど… こんどは、 BL に IUIRunner なんてものが入ってるのが気に入らないw
投稿: biac | 2008年10月27日 (月) 01時20分
お疲れ様でございました。
参照関係をいかに減らすか、いかに自然な参照関係に持ち込むかは
いつも実装時の課題ですね~。特にBusinessLogicが一切参照を持たない実装は
かなり魅力です。
インターフェースをうまく使えるようになりたい今日この頃。
投稿: D | 2008年10月26日 (日) 23時30分