初めてのDIフレームワーク
準備
- PHP5.4+で動作します。mysqlで予めテーブルを作成しておきます。
2 フォルダをつくります。
まずは手動でインジェクションするコードソースを入力して実行します。
実行してみます。
データベースにtodoが入力されたか、コンソールかツール等で確認します。
確認できましたか?OK?
では、次にcomposerのプロジェクトを作ってこのクラスをDI化してみましょう。
composerでRay.Di依存の空プロジェクトを作る
まずはcomposerをダウンロードします。
composerを使ってRay.Diを使うプロジェクトを作ります。
すると色々質問されるので、ray/diのバージョン* (最新の安定板)をインストールするように答えます。
入力の必要な質問はこれだけでした。
すると最後に表示されたcomposer.jsonが出来上がりますが、まだray/diはインストールされていません。installコマンドでインストールします。
initコマンドで作成したcomposer.jsonに従ってRay.Diとその依存ファイルとダウンロードされ、現在の依存の状態が記録されたcomposer.lockファイル、それにautoloaderを含むcomposerのファイル群もインストールされました。
Ray.Diを使ったコードを入力してsrc/フォルダを作ってその下に配置します。
src/todo3-ray-di.php
これがRay.Diを使ってDIを行っているコードです。変わった部分をそれぞれ見て行きます。
オートローダー
composerを使うと依存ファイルのオートローディングの設定が含まれた、vendor/autoload.phpというオートローダーのファイルが自動で生成されます。
Ray.DiのアノテーションはDoctrineのアノテーションを使っています。アノテーションの読み込みにはオートローダーの登録が必要で、いくつかの方法がありますがここではcomposerのオートローダーをそのまま使っています。
アノテーション
依存を受け取るメソッドには@Injectとアノテート(注釈)されています。Ray.Diはこのアノテーションを目印にして依存が必要なメソッドを割り出します。
アノテーションはクラスで、名前解決のためuse文が必要です。
モジュール
モジュールでは依存を必要とする場所に依存をどう渡すかを記述します。
AbstractModuleを継承したクラスのconfigure()というメソッド内で、bind()メソッドを使って依存を束縛(バインド=結びつけます)します。ここではPDOクラスを必要とするインジェクションポイントに作成した$pdoインスタンスを束縛しています。
これによってアノテーションの節で説明したように@injectとアノテートされPDOクラスのタイプヒントを持つ引き数には$pdoインスタンスが渡されるようになります。
インジェクター
モジュールを使って作成したインジェクターは、どの依存が求められれば何を渡せばいいかを知っています。そのインジェクターを使って’Todo’クラスを取得するとインジェクターは必要とされる依存をモジュールで決めたルールで渡し、依存解決(dependency resolution)が行われます。
ついに出来ました!!!!
$todoオブジェクト!!!
依存の問題を解決(外部の変数を外側から渡す)を自動化するために、様々な事が必要になりました。
依存が必要な箇所にアノテーションが必要です。そのアノテーションクラスのオートローディング登録も必要で、モジュールでも依存の束縛の記述、束縛を使ったインジェクターの作成をしてようやく依存解決をするインジェクターが作成されました。
1つの問題を解決するためにこれだけの事をしたのです。DIフレームワークはRayだけではありません。他のDIフレームワークも同じような、あるいはこれ以上の準備の手順の複雑さを持っています。
オーバーエンジニアリング?
オーバーエンジニアリング(作り込みのし過ぎ、過剰技術)でしょうか?
まず、他の技術同様に、説明のための単純な例で実利を感じる事は往々にして難しい事は頭に入れておく必要があります。例えば、HelloWorldのサンプルでフレームワークのメリットを実感する事はなかなか難しいでしょう。
DIフレームワークの使用がオーバーエンジアリングか、クラス名のハードコーディングがアンダーエンジニアリングなのか、その辺りの判断を直感で出すのはひとまず置いといて、Ray DIフレームワークの使い方の実例をもう少し見て行きましょう。
…続く