はじめに
皆さんは、Seasarファウンデーションをご存知でしょうか。2005年12月にNPO(非営利団体)として運営が開始されたオープンソースソフトウェア開発コミュニティです。
S2Container.PHP5は、Seasarファウンデーションの1プロジェクトとして開発が進められています。S2Containerとは、DI(Dependency Injection)とAOP(Aspect Oriented Programming)をサポートする軽量コンテナで、Javaで開発されました。S2Container.PHP5はS2ContainerをPHP5に移植したものです。2005年の5月にSeasarファウンデーションで開発がスタートし、2006年4月29日にS2Container.PHP5-1.1.0が正式にリリースされています。
本稿では、PHP5環境で動作するS2Container.PHP5について紹介します。
対象読者
PHP-5.1以降を用いて開発する方を対象とします。
必要な環境
筆者の環境は次のとおりです。
- OS: WindowsXP
- PHP: PHP-5.1.4-Win32
付属サンプルについては、Debian GNU/Linux、PHP-5.1.4 でも動作確認しています。筆者は未確認ですが、その他のUNIX/Linux環境でも問題なく動作すると思います。
コンテナとコンポーネント
まずはじめに、「S2Container」の「コンテナ」とはなんでしょうか。コンテナと聞くと、筆者は船舶や貨車に積む大きな鉄の箱をイメージします。S2Containerも「なにかを入れる箱」という意味では元の意味と通ずるところがあります。S2Containerにはコンポーネントを入れます。また、コンテナの中にコンテナを入れることもできます。S2Containerはコンテナやコンポーネントを管理します。
では、「コンポーネント」とはなんでしょうか。コンポーネントは、ある1つの機能を持ちます。1つの機能は、1つのクラスで実装される場合もあれば、複数のクラスから構成されている場合もあります。ある機能を使いたい場合、その機能を持つコンポーネントをS2Containerから取り出して使用することになります。この時、その機能が複数のクラスから構成されている場合は、S2Containerは必要なクラスを持つコンポーネントを組み合わせた形で返してくれます。これが、S2ContainerにおけるDI(Dependency Injection)になります。
DIの種類
S2Containerが提供するDIの種類は次の3つです。
- コンストラクタ・インジェクション
- セッター・インジェクション
- メソッド・インジェクション
setXxx
という命名規則に従ったメソッドです。Xxx
にはプロパティ名を用います。3種類のDIを組み合わせて使うこともできます。筆者は主にセッター・インジェクションを使用し、特殊な初期化が必要な場合にメソッド・インジェクションを使っています。
diconファイルについて
S2Containerのイメージはコンテナ(箱)であり、最初はからっぽです。そのため、S2Containerを使用する前にコンポーネントを入れておく必要があります。どのようなコンポーネントを入れておくのか、それらのコンポーネントの情報、および他のコンポーネントとの関係(Dependency)などを設定するのがdiconファイルになります。
diconファイルは「ダイコンファイル」と呼びます。diconファイルはXMLで記述します。XMLのタグは9種類あり、各タグの属性で細かい設定ができます。よく使用するのは9つ中、4つほどです。本稿でも説明に出てくるタグは次の3つです。
- componentsタグ
- componentタグ
- propertyタグ
component
タグの子タグです。property
タグで設定された値がセッター・インジェクションされます。インターフェイスを用いることの利点
PHP5からインターフェイス(interface)を定義できるようになりました。インターフェイスと実装を分離することにより、クラス同士の依存関係を軽減できます。このため仕様変更への柔軟な対応が可能になるなど、インターフェイスを定義することが推奨されます。S2Containerを使用する場合は、コンポーネントごとにインターフェイスを定義するとさらに利点が得られます。
S2Containerには自動バインディングという機能があり、コンポーネントの依存関係を自動的に解決します。この際、自動解決を行うための情報源としてインターフェイス定義を使用します。S2Containerは、クラスのコンストラクタやセッターメソッドの引数が、インターフェイスによってType Hintingされているかどうかを調べます。Type Hintingされている場合は、そのクラスはそのインターフェイスを実装しているクラスが必要なのだと判断し、DIを実施します。自動バインディング機能を用いるとdiconファイルに依存関係情報を記述する必要がなくなるため、diconファイルの設定量を減少できます。