DI コンテナがコードに出現するのは dependency lookup が行われている兆候

Dependency Injection (DI) コンテナを基盤にしたアーキテクチャを採用している場合に、(プロダクト|テスト)コードに DI コンテナが登場するのは dependency lookup (依存コンポーネントの検索)を行っている兆候と考えることが出来ます(もちろん必要があってコンテナの injection が行われている場合もあります)。 テストに DI コンテナが出現することに気付いたら、 Dependency lookup から Dependency Injection (DI) へのリファクタリングの契機とすることもできるでしょう。 続きを読む
26
dakatsuka @d_akatsuka

DIコンテナをモック化するとかなりテストがしやすい気がする

2013-05-10 10:29:09
Takuto Wada @t_wada

@d_akatsuka テストに DI コンテナが登場するのは、 dependency injection ではなく dependency lookup になってしまっている兆候ではないでしょうか (もっと粒度の大きいテストの話だったらすみません)

2013-05-10 10:39:23
dakatsuka @d_akatsuka

@t_wada 複数のリポジトリからデータを取得してごにょごにょするサービスクラスを作っているのですが、リポジトリの取得がコンテナ経由になってしまうんですよね…。Smyfony2は良いFWだと思うのですが、如何せん情報が少なくて試行錯誤してます

2013-05-10 10:45:13
Takuto Wada @t_wada

@d_akatsuka サービスクラスにコンストラクタやセッターを定義して、 DI 定義で constructor injection や setter injection するのはいかがでしょう http://t.co/hIf0boFS1w

2013-05-10 10:50:53
dakatsuka @d_akatsuka

@t_wada 今はSetter injectionでコンテナを突っ込む形にしているのですが、コンテナではなく必要なものだけ(例えばdoctrine)をinjectするべきという事でしょうか

2013-05-10 11:06:29
dakatsuka @d_akatsuka

ContainerAwareを発見して先走った感

2013-05-10 11:07:06
Takuto Wada @t_wada

@d_akatsuka そのとおりです。DI の大事なところは lookup の知識をプロダクトコードから排して全体の複雑性を下げることです。必要なものを探すのではなく、与えてもらう構造を作ります。今回で言えば、リポジトリ二つのセッターがあればそれで済む、というのが良い状態ですね

2013-05-10 11:11:02
dakatsuka @d_akatsuka

@t_wada 勉強になりました!ありがとうございます

2013-05-10 11:16:27
Hidenori Goto | COO and CTO at KabuK Style @hidenorigoto

@d_akatsuka @t_wada Symfony2/Doctrineの場合ちょっと特殊でエンティティリポジトリはDoctrine EntityManager経由で取得しないといけないんですよね。

2013-05-10 11:20:40
Hidenori Goto | COO and CTO at KabuK Style @hidenorigoto

@d_akatsuka @t_wada (つづき) なので、サービスクラスにEntityManagerをインジェクトし、サービスクラス内ではEntityManagerからリポジトリオブジェクトを取得する形で折り合いをつけています。

2013-05-10 11:22:09
Takuto Wada @t_wada

@hidenorigoto @d_akatsuka なんと、そうでしたか…! では EM を inject するしかないんですかね。なかなか悩ましいですね。

2013-05-10 11:22:59
dakatsuka @d_akatsuka

@t_wada @hidenorigoto お、Doctrineは特殊なんですね。。。大変参考になりました。setEntityManage()を作って試してみますー

2013-05-10 11:28:08
Atsuhiro Kubo @iteman

@t_wada @hidenorigoto @d_akatsuka DI 定義の factory_service を使えばインジェクションできますよ。

2013-05-10 11:36:15
Atsuhiro Kubo @iteman

@t_wada @hidenorigoto @d_akatsuka ただ、サービスクラス等で結局 $em->flush() 等を使うので EntityManager だけでもいいと思いますが、より明示的にしたければそれぞれをインジェクションするのが良いかと思います。

2013-05-10 11:38:23
Takuto Wada @t_wada

@iteman @hidenorigoto @d_akatsuka 補足ありがとうございます。私はできるだけ lookup を排したいので、明示的にそれぞれ injection するのが好みだなと思いました。

2013-05-10 11:45:20
Atsuhiro Kubo @iteman

Doctrine ベースのリポジトリを DI サービスとして定義する例 https://t.co/foU59zqExL #symfony #doctrine

2013-05-10 11:55:59
Atsuhiro Kubo @iteman

Doctine リポジトリのインジェクションは少々テクニカルなので状況に合わせて選択すると良いと思います。

2013-05-10 11:58:44
Atsuhiro Kubo @iteman

@t_wada @hidenorigoto @d_akatsuka そうですね、私も明示的にインジェクションする方が良いと考えています。

2013-05-10 12:05:59
Kakutani Shintaro @kakutani

@t_wada ここ数日またブクマが増えてたのはこれか…

2013-05-13 15:54:49
Takuto Wada @t_wada

@kakutani 突発的に DI おじさん業を執り行った結果、本家へ影響があったとは…!

2013-05-13 15:56:20
🍻 @kompiro

@t_wada Dependency lookupをするとなんでいかんのか、っていう点もこの話の流れに必要な気がしました。JavaでいうPOJOではなくなるからイカンっていうこと(移植性)や、テストのセットアップフェーズにコンテナも作らないかん(スローテストへの第一歩)とか。

2013-05-13 15:58:19
Takuto Wada @t_wada

@kompiro そのとおりですね。大事な視点なので togetter に加えますね!

2013-05-13 15:59:23
🍻 @kompiro

@t_wada ありがとうございます。先人が踏んだ地雷を避けられるとみんなハッピーになれるから、こういうノウハウは共有したいですねー。って検索したらこんなスライドが…。http://t.co/COYoYcCHm0 いろいろありがとうございます。

2013-05-13 16:02:42