yotiky Tech Blog

とあるエンジニアの備忘録

IoCとService LocatorとDIの関係

目次

概要

連載的に書き始めたアーキテクチャのお話で、IoC、DIという単語が出てきたので軽くまとめておく。

制御の反転と実現

登場人物はIoC、Service Locator、DI。すべてパターンと呼ばれるものの一種。

IoC」は「Inversion of Control」の略で、日本語だと「制御の反転」。
インターフェイスを間に挟み仲介することで、具象クラスが何になるかは外部で決めるようにするというパターン。
これ自体は汎用的な名前で定義されており、続く「Service Locator」、「DI」がそれを実現するためのパターンとして定義される。

f:id:yotiky:20180928053641p:plain

「Service Locator」は、SingletonなFactoryに、生成したインスタンスをキャッシュする機能を備えたようなもの。
事前にService Locatorに使う具象クラスを定義し、使う人がService Locatorに問い合わせると良しなにインスタンスを返してくれる。それが何の具象クラスかは知らない。

f:id:yotiky:20180928053648p:plain

「DI」は、「Dependency Injection」の略で、日本語だと「依存性の注入」。
呼び出す側が使う人に具象クラスを渡してあげるパターン。使う人はインターフェイスで受け取るので、それが何の具象クラスかは知らない。

f:id:yotiky:20180928053656p:plain

Injection(注入する方法)はいくつかあって、コンストラクタ、セッター(プロパティ)、フィールド、メソッドなど。インターフェイスってのもあるらしい。

「DI」自体はフレームワークがなくても実装可能ではある。
しかし「DI」には、「DI コンテナ」が多く存在する。「DI パターン」を実現するために有効なフレームワークだ。
「DI コンテナ」により、先の多様なInjectionに対応したり、Injectionの処理自体を裏で引き受けてくれたり、インスタンスのライフサイクルを管理したりと手厚いサポート受けられるようになる。前述のInjectionに対しては、属性をマーキングすることで実現する方法も手にれられる。

f:id:yotiky:20180928055240p:plain

「DI」自体は、外から注入するというだけのパターンであるが、「DI コンテナ」は「Service Locator」の役割も包含してしまっているように思える。
そりゃみんな「Service Locator」は置き去りにするわけだ。
ついでに、機能的に多くを必要としないからか「Service Locator コンテナ」は見かけたことがない。「IoC コンテナ」と言ったときは間違いなく「DI コンテナ」のことだろう。

Injectionは、コンストラクタが推奨されているようだ。インスタンスが生成された時には、必要な初期化が終わってるべきだというわけ。
ただし、Unityに限っては多くの生成処理がUnity側にあるので、コンストラクタが使えない。そのため次点でメソッドとなるらしい。

「Service Locator」と「DI」の使い分けについては、2004年と古いがMartin Fowlerの考察が載っていて興味深い。1

参考にさせて頂いたサイト