第3章 S2Container.PHPリファレンス

目次

3.1. S2Container リファレンス
3.1.1. S2Containerの生成
3.1.2. コンポーネントの取得
3.1.3. 自動バインディングによるDI
3.1.4. マニュアル設定によるDI
3.1.5. バインディングタイプの設定
3.1.6. インスタンスタイプの設定
3.1.7. ConstructClosureによるコンポーネントの生成
3.2. S2ApplicationContext リファレンス
3.2.1. コンポーネントのインポート
3.2.2. S2Containerの生成
3.2.3. コンポーネントの選択
3.2.4. コンポーネントの手動登録
3.2.5. 自動アスペクト
3.2.6. アノテーション
3.2.7. Singleton S2Container インスタンスの管理
3.2.8. S2ApplicationContextのInitialize
3.3. S2ContainerFactory リファレンス
3.3.1. ダイコンファイルの作成
3.3.2. S2Containerの生成
3.4. ダイコンファイル タグリファレンス
3.4.1. DOCTYPE (必須)
3.4.2. componentsタグ (必須)
3.4.3. includeタグ (任意)
3.4.4. componentタグ (任意)
3.4.5. argタグ (任意)
3.4.6. propertyタグ (任意)
3.4.7. initMethodタグ (任意)
3.4.8. aspectタグ (任意)
3.4.9. metaタグ (任意)
3.4.10. descriptionタグ (任意)
3.5. S2Container 設定ファイル

3.1. S2Container リファレンス

3.1.1. S2Containerの生成

S2Containerの生成はS2ApplicationContextクラス、 またはS2ContainerFactoryクラスのcreateメソッドで行います。

S2ApplicationContextクラスを用いる場合は、 importメソッドでファイルシステムからクラス定義ファイルを検索し、検索結果クラスをコンポーネントとして持つS2Containerを 生成します。

<?php
require_once('S2Container/S2Container.php');
seasar\container\S2ApplicationContext::import('/path/to/classes');
$container = seasar\container\S2ApplicationContext::create();

S2ContainerFactoryクラスを用いる場合は、 コンポーネントの定義を記述したダイコンファイルを読み込んでS2Containerを生成します。

<?php
require_once('S2Container/S2Container.php');
$container = seasar\container\factory\S2ContainerFactory::create('/path/to/diconファイル');


3.1.2. コンポーネントの取得

S2Containerからコンポーネントを取り出すには、次のメソッドを使用します。

S2Container::getComponent($componentKey)

引数にはコンポーネントのクラス名、もしくはコンポーネント名を指定します。 S2Containerの中に指定したクラスを実装しているコンポーネントが複数ある場合、S2Containerは どのコンポーネントを返せばよいのか判断できないためTooManyRegistrationRuntimeExceptionをスローします。 実装コンポーネントがユニークに決まるクラス名を指定してください。
コンポーネント名で取得する場合も同様に、1つのS2Containerの中でユニークとなるコンポーネント名を指定します。 同じ名前をもつコンポーネントが複数登録されている場合は、TooManyRegistrationRuntimeExceptionが発生します。

例として、次のようにダイコンファイルでコンポーネントが定義されているとします。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN"
"http://www.seasar.org/dtd/components21.dtd">
<components>
    <component name="action" class="example\IndexAction" />
</components>

コンポーネント名を指定してコンポーネントを取得する場合は次のようになります。

<?php
require_once('S2Container/S2Container.php');
$container = seasar\container\impl\S2ContainerFactory::create('/path/to/diconファイル');
$component = $container->getComponent('action');

クラス名を指定してコンポーネントを取得する場合は次のようになります。

<?php
require_once('S2Container/S2Container.php');
$container = seasar\container\impl\S2ContainerFactory::create('/path/to/diconファイル');
$component = $container->getComponent('example\IndexAction');

 namespace を含まないクラス名でもコンポーネントを取得することができます。

<?php
require_once('S2Container/S2Container.php');
$container = seasar\container\impl\S2ContainerFactory::create('/path/to/diconファイル');
$component = $container->getComponent('IndexAction');

 クラス名の先頭文字を小文字としたコンポーネント名で取得することもできます。

<?php
require_once('S2Container/S2Container.php');
$container = seasar\container\impl\S2ContainerFactory::create('/path/to/diconファイル');
$component = $container->getComponent('indexAction');


3.1.3. 自動バインディングによるDI

S2Containerの自動バインディングは、コンポーネント間の依存関係をプロパティやセッターメソッドのタイプヒントで指定される クラスやインターフェースの情報で解決します。 自動バインディングによるDependency Injectionには次の3つのタイプがあります。

  • プロパティ・インジェクション
  • セッターメソッド・インジェクション
  • コンストラクタ・インジェクション

プロパティ・インジェクション. 

プロパティ・インジェクションでは、アクセス修飾子がpublicなプロパティにDependency Injectionを行います。

<?php
class Action {

    /**
     * @var Service
     */
    public $service = null;

    /**
     * アクション実装メソッド
     */
    public function execute() {
        $result = $this->service->add(2,3);    
    }
}

publicプロパティのデフォルト値がnullと判断された場合は、プロパティ名をキーとするコンポーネントがDIされます。 上記のサンプルでは、「service」コンポーネントがDIされます。
デフォルト値が null の publicプロパティへのDIを実施したくない場合は、 seasar\container\Config::$DI_PROPERTY_NULL に false を設定します。

seasar\container\Config::$DI_PROPERTY_NULL = false;

DIするコンポーネントを指定したい場合は プロパティのデフォルト値にタイプヒントを記述します。 タイプヒントは「S2Binding コンポーネント名」と記述します。また、複数のコンポーネントをまとめて配列としDIすることができます。 配列としてDIする場合は、タイプヒントに「S2Binding コンポーネント名[]」と記述します。 次のようなアクションクラスをカレントディレクトリにclasses/Action.phpとして保存します。

<?php
class Action {

    /**
     * @var Service
     */
    public $service = 'S2Binding Service';

    /**
     * アクション実装メソッド
     */
    public function execute() {
        $result = $this->service->add(2,3);    
    }
}

プロパティのデフォルト値のコンポーネント名は省略できます。コンポーネント名が省略された場合は、プロパティ名が コンポーネント名として扱われます。次の例では、コンポーネント名は「service」となります。

    /**
     * @var Service
     */
    public $service = 'S2Binding';

seasar\container\Config::$PROPERTY_TYPEHINT_KEY に任意の文字列を指定することで、 プロパティのタイプヒントのキーを設定できます。$PROPERTY_TYPEHINT_KEYに「DI」を設定した場合は、 次のようにpublic プロパティのデフォルト値を設定できます。 seasar\container\Config::$PROPERTY_TYPEHINT_KEYのデフォルト値は「S2Binding」です。

seasar\container\Config::$PROPERTY_TYPEHINT_KEY = 'DI';
    /**
     * @var Service
     */
    public $service = 'DI Service';

次のようなサービスクラスをカレントディレクトリに classes/Service.php として保存します。

<?php
class Service {

    /**
     * 足し算を行います。
     *
     * @param integer $a
     * @param integer $b
     * @return integer
     */
    public function add($a, $b) {
        return $a + $b;    
    }
}

S2ApplicationContextクラスを用いてコンテナを生成し、アクションコンポーネントを取得します。 取得したアクションコンポーネントにはS2Containerの自動バインディング機能によって、サービスコンポーネントがDIされています。

<?php
require_once('S2Container/S2Container.php');

seasar\container\S2ApplicationContext::import(dirname(__FILE__) . '/classes');
$container = seasar\container\S2ApplicationContext::create();
$action    = $container->getComponent('Action');

$action->execute();

S2ContainerFactoryクラスを用いてコンテナを生成する場合は次のようなダイコンファイルを用意します。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN"
"http://www.seasar.org/dtd/components21.dtd">
<components>
    <component class="Action"/>
    <component class="Service"/>
</components>

S2ContainerFactoryクラスを用いてコンテナを生成し、アクションコンポーネントを取得します。 取得したアクションコンポーネントにはS2Containerの自動バインディング機能によって、サービスコンポーネントがDIされています。

<?php
require_once('S2Container/S2Container.php');

seasar\util\ClassLoader::import(dirname(__FILE__) . '/classes');
$container = seasar\container\S2ContainerFactory::create('/path/to/diconファイル');
$action    = $container->getComponent('Action');

$action->execute();

[注意]NOTE

このExampleは example/AutoDI/property と example/AutoDI/property_array にあります。


セッターメソッド・インジェクション. 

セッターメソッド・インジェクションでは、任意のプロパティにセッターメソッドを使用してDependency Injectionを行います。 セッターメソッドには命名規則があります。プロパティ名が「service」 の場合、先頭一文字を大文字とし「set」を先頭に付加して、 「setService」がセッターメソッド名となります。

例として、あるアクションにサービスをDIする場合を次に示します。
アクションクラスにはサービスを設定するセッターメソッドを実装します。セッターメソッドの引数は、サービスクラスでタイプヒントします。 次のようなアクションクラスをカレントディレクトリに classes/Action.php として保存します。

<?php
class Action {

    /**
     * @var Service
     */
    private $service = null;

    /**
     * サービスのセッターメソッド
     *
     * @param Service $service
     */
    public function setService(Service $service) {
        $this->service = $service;    
    }

    /**
     * アクション実装メソッド
     */
    public function execute() {
        $result = $this->service->add(2,3);    
    }
}

次のようなサービスクラスをカレントディレクトリに classes/Service.php として保存します。

<?php
class Service {

    /**
     * 足し算を行います。
     *
     * @param integer $a
     * @param integer $b
     * @return integer
     */
    public function add($a, $b) {
        return $a + $b;    
    }
}

S2ApplicationContextクラスを用いてコンテナを生成し、アクションコンポーネントを取得します。 取得したアクションコンポーネントにはS2Containerの自動バインディング機能によって、サービスコンポーネントがDIされています。

<?php
require_once('S2Container/S2Container.php');

seasar\container\S2ApplicationContext::import(dirname(__FILE__) . '/classes');
$container = seasar\container\S2ApplicationContext::create();
$action    = $container->getComponent('Action');

$action->execute();

S2ContainerFactoryクラスを用いてコンテナを生成する場合は次のようなダイコンファイルを用意します。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN"
"http://www.seasar.org/dtd/components21.dtd">
<components>
    <component class="Action"/>
    <component class="Service"/>
</components>

S2ContainerFactoryクラスを用いてコンテナを生成し、アクションコンポーネントを取得します。 取得したアクションコンポーネントにはS2Containerの自動バインディング機能によって、サービスコンポーネントがDIされています。

<?php
require_once('S2Container/S2Container.php');

seasar\util\ClassLoader::import(dirname(__FILE__) . '/classes');
$container = seasar\container\S2ContainerFactory::create('/path/to/diconファイル');
$action    = $container->getComponent('Action');

$action->execute();

[注意]NOTE

このExampleは example/AutoDI/setter にあります。


コンストラクタ・インジェクション. 

コンストラクタ・インジェクションでは、クラスのコンストラクタ引数を用いて Dependency Injection を行います。

例として、あるアクションにサービスをDIする場合を次に示します。
アクションクラスではサービスを設定するため、コンストラクタ引数を用意しサービスクラスでタイプヒントします。 次のようなアクションクラスをカレントディレクトリに classes/Action.php として保存します。

<?php
class Action {

    /**
     * @var Service
     */
    private $service = null;

    /**
     * Actionクラスを構築します。
     *
     * @param Service $service
     */
    public function __construct(Service $service) {
        $this->service = $service;    
    }

    /**
     * アクション実装メソッド
     */
    public function execute() {
        $result = $this->service->add(2,3);    
    }
}

次のようなサービスクラスをカレントディレクトリに classes/Service.php として保存します。

<?php
class Service {

    /**
     * 足し算を行います。
     *
     * @param integer $a
     * @param integer $b
     * @return integer
     */
    public function add($a, $b) {
        return $a + $b;    
    }
}

S2ApplicationContextクラスを用いてコンテナを生成し、アクションコンポーネントを取得します。 取得したアクションコンポーネントにはS2Containerの自動バインディング機能によって、サービスコンポーネントがDIされています。

<?php
require_once('S2Container/S2Container.php');

seasar\container\S2ApplicationContext::import(dirname(__FILE__) . '/classes');
$container = seasar\container\S2ApplicationContext::create();
$action    = $container->getComponent('Action');

$action->execute();

S2ContainerFactoryクラスを用いてコンテナを生成する場合は次のようなダイコンファイルを用意します。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN"
"http://www.seasar.org/dtd/components21.dtd">
<components>
    <component class="Action"/>
    <component class="Service"/>
</components>

S2ContainerFactoryクラスを用いてコンテナを生成し、アクションコンポーネントを取得します。 取得したアクションコンポーネントにはS2Containerの自動バインディング機能によって、サービスコンポーネントがDIされています。

<?php
require_once('S2Container/S2Container.php');

seasar\util\ClassLoader::import(dirname(__FILE__) . '/classes');
$container = seasar\container\S2ContainerFactory::create('/path/to/diconファイル');
$action    = $container->getComponent('Action');

$action->execute();

[注意]NOTE

このExampleは example/AutoDI/consructor にあります。


3.1.4. マニュアル設定によるDI

マニュアル設定によるDependency Injectionには次の4つのタイプがあります。

  • プロパティ・インジェクション
  • セッターメソッド・インジェクション
  • コンストラクタ・インジェクション
  • InitMethod・インジェクション

プロパティ・インジェクション. 

プロパティ・インジェクションとは、アクセス修飾子がpublicなプロパティにDependency Injectionを行います。

コメントアノテーションで設定する. 

次のようなアクションクラスをカレントディレクトリにclasses/Action.phpとして保存します。 各プロパティのコメントアノテーションで、インジェクションを行う値やExpression、他のコンポーネントへの参照を記述します。

<?php
class Action {

    /**
     * @S2Binding('"seasar"')
     */
    public $name    = null;     // 文字列 seasar がインジェクションされます。    

    /**
     * @S2Binding('2000 + 8')
     */
    public $year    = null;     // 数値 2008 がインジェクションされます。

    /**
     * @S2Binding('Service')
     */
    public $service = null;     // Service コンポーネントがインジェクションされます。
}

次のようなサービスクラスをカレントディレクトリにclasses/Service.phpとして保存します。

<?php
class Service {

    /**
     * 足し算を行います。
     *
     * @param integer $a
     * @param integer $b
     * @return integer
     */
    public function add($a, $b) {
        return $a + $b;    
    }
}

S2ApplicationContextクラスを用いてコンテナを生成し、アクションコンポーネントを取得します。 取得したアクションコンポーネントにはアノテーションで設定した値やサービスコンポーネントがDIされています。

<?php
require_once('S2Container/S2Container.php');

seasar\container\S2ApplicationContext::import(dirname(__FILE__) . '/classes');
$container = seasar\container\S2ApplicationContext::create();
$action    = $container->getComponent('Action');

var_dump($action);


diconファイルで設定する. 

S2Containerの定義ファイルである diconファイルで設定する場合は、次のような内容を記述します。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN"
"http://www.seasar.org/dtd/components21.dtd">
<components>
    <component class="Action">
        <property name="name">"seasar"</property>
        <property name="year">2000 + 8</property>
        <property name="service">Service</property>
    </component>
    <component class="Service" />
</components>

コンポーネントのプロパティは、componentタグの子タグであるpropertyタグを使って指定します。 name属性でプロパティ名を指定します。 propertyタグのボディには、クォートで囲まれた値、PHPを記述したExpression、他のコンポーネントへの参照を設定できます。

次のようなアクションクラスをカレントディレクトリに classes/Action.php として保存します。 アクションクラスには、各プロパティのセッターメソッドを記述します。

<?php
class Action {
    public $name    = null;     // 文字列 seasar がインジェクションされます。    
    public $year    = null;     // 数値 2008 がインジェクションされます。
    public $service = null;     // Service コンポーネントがインジェクションされます。
}

次のようなサービスクラスをカレントディレクトリに classes/Service.php として保存します。

<?php
class Service {

    /**
     * 足し算を行います。
     *
     * @param integer $a
     * @param integer $b
     * @return integer
     */
    public function add($a, $b) {
        return $a + $b;    
    }
}

S2ContainerFactoryクラスを用いてコンテナを生成し、アクションコンポーネントを取得します。 取得したアクションコンポーネントにはダイコンファイルで設定した値やサービスコンポーネントがDIされています。

<?php
require_once('S2Container/S2Container.php');

seasar\util\ClassLoader::import(dirname(__FILE__) . '/classes');
$container = seasar\container\S2ContainerFactory::create('/path/to/diconファイル');
$action    = $container->getComponent('Action');

var_dump($action);

[注意]NOTE

このExampleは example/ManualDI/property と example/ManualDI/property_array にあります。


セッターメソッド・インジェクション. 

セッター・インジェクションとは、任意のプロパティにセッターメソッドを使用してDependency Injectionを行います。

コメントアノテーションで設定する. 

次のようなアクションクラスをカレントディレクトリに classes/Action.php として保存します。 各プロパティのセッターメソッドを記述します。セッターメソッドにはコメントアノテーションで、インジェクションを 行う値やExpression、他のコンポーネントへの参照を記述します。 参照しているコンポーネントが複数の場合はセッターメソッドのタイプヒントに array を指定することで配列としてDIすることができます。 (array タイプヒントが成されていない場合は、TooManyRegistrationRuntimeException がスローされます。)

<?php
class Action {
    private $name    = null;
    private $year    = null;
    private $service = null;

    /**
     * @S2Binding('"seasar"')
     */
    public function setName($name) {
        $this->name = $name;    // 文字列 seasar がインジェクションされます。    
    }
    
    /**
     * @S2Binding('2000 + 8')
     */
    public function setYear($year) {
        $this->year = $year;    // 数値 2008 がインジェクションされます。
    }
    
    /**
     * @S2Binding('Service')
     */
    public function setService(Service $service) {
        $this->service  = $service     // Service コンポーネントがインジェクションされます。
    }
}

次のようなサービスクラスをカレントディレクトリに classes/Service.php として保存します。

<?php
class Service {

    /**
     * 足し算を行います。
     *
     * @param integer $a
     * @param integer $b
     * @return integer
     */
    public function add($a, $b) {
        return $a + $b;    
    }
}

S2ApplicationContextクラスを用いてコンテナを生成し、アクションコンポーネントを取得します。 取得したアクションコンポーネントにはアノテーションで設定した値やサービスコンポーネントがDIされています。

<?php
require_once('S2Container/S2Container.php');

seasar\container\S2ApplicationContext::import(dirname(__FILE__) . '/classes');
$container = seasar\container\S2ApplicationContext::create();
$action    = $container->getComponent('Action');

var_dump($action);


diconファイルで設定する. 

S2Containerの定義ファイルである diconファイルで設定する場合は、次のような内容を記述します。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN"
"http://www.seasar.org/dtd/components21.dtd">
<components>
    <component class="Action">
        <property name="name">"seasar"</property>
        <property name="year">2000 + 8</property>
        <property name="service">Service</property>
    </component>
    <component class="Service" />
</components>

コンポーネントのプロパティは、componentタグの子タグであるpropertyタグを使って指定します。 name属性でプロパティ名を指定します。 propertyタグのボディには、クォートで囲まれた値、PHPを記述したExpression、他のコンポーネントへの参照を設定できます。 参照しているコンポーネントが複数の場合はセッターメソッドのタイプヒントに array を指定することで配列としてDIすることができます。 (array タイプヒントが成されていない場合は、TooManyRegistrationRuntimeException がスローされます。)

次のようなアクションクラスをカレントディレクトリに classes/Action.php として保存します。 アクションクラスには、各プロパティのセッターメソッドを記述します。

<?php
class Action {
    private $name    = null;
    private $year    = null;
    private $service = null;

    public function setName($name) {
        $this->name = $name;    // 文字列 seasar がインジェクションされます。    
    }
    
    public function setYear($year) {
        $this->year = $year;    // 数値 2008 がインジェクションされます。
    }
    
    public function setService(Service $service) {
        $this->service  = $service;     // Service コンポーネントがインジェクションされます。
    }
}

次のようなサービスクラスをカレントディレクトリに classes/Service.php として保存します。

<?php
class Service {

    /**
     * 足し算を行います。
     *
     * @param integer $a
     * @param integer $b
     * @return integer
     */
    public function add($a, $b) {
        return $a + $b;    
    }
}

S2ContainerFactoryクラスを用いてコンテナを生成し、アクションコンポーネントを取得します。 取得したアクションコンポーネントにはダイコンファイルで設定した値やサービスコンポーネントがDIされています。

<?php
require_once('S2Container/S2Container.php');

seasar\util\ClassLoader::import(dirname(__FILE__) . '/classes');
$container = seasar\container\S2ContainerFactory::create('/path/to/diconファイル');
$action    = $container->getComponent('Action');

var_dump($action);

[注意]NOTE

このExampleは example/ManualDI/setter と example/ManualDI/setter_array にあります。


コンストラクタ・インジェクション. 

コンストラクタ・インジェクションとは、コンストラクタの引数値にDependency Injectionを実施します。
S2Containerの定義ファイルには、次のような内容を記述します。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN"
"http://www.seasar.org/dtd/components21.dtd">
<components>
    <component class="Action">
        <arg>"seasar"</arg>
        <arg>2000 + 8</arg>
        <arg>Service</arg>
    </component>
    <component class="Service" />
</components>

コンポーネントのコンストラクタの引数はcomponentタグの子タグであるargタグを使って指定します。 argタグのボディには、クォートで囲まれた値、PHPを記述したExpression、他のコンポーネントへの参照を設定できます。 参照しているコンポーネントが複数の場合はコンストラクタ引数のタイプヒントに array を指定することで配列としてDIすることができます。 (array タイプヒントが成されていない場合は、TooManyRegistrationRuntimeException がスローされます。)

アクションクラスのコンストラクタでは次のように、3つの引数を受け取ります。

<?php
class Action {
    private $name    = null;
    private $year    = null;
    private $service = null;

    public function __construct($name, $year, Service $service) {
        $this->name    = $name;    // 文字列 seasar がインジェクションされます。
        $this->year    = $year;    // 数値 2008 がインジェクションされます。
        $this->service = $service; // service コンポーネントがインジェクションされます。
    }
}

次のようなサービスクラスをカレントディレクトリに classes/Service.php として保存します。

<?php
class Service {

    /**
     * 足し算を行います。
     *
     * @param integer $a
     * @param integer $b
     * @return integer
     */
    public function add($a, $b) {
        return $a + $b;    
    }
}

S2ContainerFactoryクラスを用いてコンテナを生成し、アクションコンポーネントを取得します。 取得したアクションコンポーネントにはダイコンファイルで設定した値やサービスコンポーネントがDIされています。

<?php
require_once('S2Container/S2Container.php');

seasar\util\ClassLoader::import(dirname(__FILE__) . '/classes');
$container = seasar\container\S2ContainerFactory::create('/path/to/diconファイル');
$action    = $container->getComponent('Action');

var_dump($action);

[注意]NOTE

このExampleは example/ManualDI/constructor と example/ManualDI/constructor_array にあります。


InitMethod・インジェクション. 

InitMethod・インジェクションとは、アクセス修飾子がpublicな任意のメソッドでDependency Injectionを実施します。
S2Containerの定義ファイルには、次のような内容を記述します。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN"
"http://www.seasar.org/dtd/components21.dtd">
<components>
    <component class="Action">
        <initMethod name="setName">
            <arg>"seasar"</arg>
        </initMethod>
        <initMethod name="setYear">
            <arg>2000 + 8</arg>
        </initMethod>
        <initMethod>
            $component->setService('new Service');
        </initMethod>
    </component>
</components>

InitMethodは、componentタグの子タグであるinitMthodeタグでメソッドを指定します。 メソッドの引数はargタグを使って指定します。argタグのボディには、クォートで囲まれた値、PHPを記述したExpression、他のコンポーネントへの参照を設定できます。

次のようなアクションクラスをカレントディレクトリに classes/Action.php として保存します。 アクションクラスにはInitMethodを実装します。

<?php
class Action {
    private $name    = null;
    private $year    = null;
    private $service = null;

    public function setName($name) {
        $this->name = $name;    // 文字列 seasar がインジェクションされます。    
    }
    
    public function setYear($year) {
        $this->year = $year;    // 数値 2008 がインジェクションされます。
    }
    
    public function setService(Service $service) {
        $this->service  = $service;     // Service コンポーネントがインジェクションされます。
    }
}

次のようなサービスクラスをカレントディレクトリにclasses/Service.phpとして保存します。

<?php
class Service {

    /**
     * 足し算を行います。
     *
     * @param integer $a
     * @param integer $b
     * @return integer
     */
    public function add($a, $b) {
        return $a + $b;    
    }
}

S2ContainerFactoryクラスを用いてコンテナを生成し、アクションコンポーネントを取得します。 取得したアクションコンポーネントにはダイコンファイルで設定した値やサービスコンポーネントがDIされています。

<?php
require_once('S2Container/S2Container.php');

seasar\util\ClassLoader::import(dirname(__FILE__) . '/classes');
$container = seasar\container\S2ContainerFactory::create('/path/to/diconファイル');
$action    = $container->getComponent('Action');

var_dump($action);

[注意]NOTE

このExampleは example/ManualDI/method にあります。


3.1.5. バインディングタイプの設定

S2Containerでは、コンポーネント単位でバインディングタイプを指定できます。バインディングタイプは次の2つがあります。

表3.1 バインディングタイプ

autoBinding説明
auto (default) コンストラクタの引数が明示的に指定されている場合は、それに従います。
コンストラクタの引数が指定されていない場合は、タイプヒント情報により自動的にバインドします。
プロパティが明示的に指定されている場合は、それに従います。
プロパティが指定されていない場合は、タイプヒント情報により自動的にバインドします。
none コンストラクタの引数が明示的に指定されている場合は、それに従います。
プロパティが明示的に指定されている場合は、それに従います。

コメントアノテーションでバインディングタイプを指定する場合は次のようになります。

<?php
/**
 * @S2Compnent('autoBinding' => 'none')
 */
class Service {}

S2Containerの定義ファイルで設定する場合は、次のような内容を記述します。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN"
"http://www.seasar.org/dtd/components21.dtd">
<components>
    <component class="Service" autoBinding="none"/>
</components>

3.1.6. インスタンスタイプの設定

S2Containerでは、コンポーネント単位でインスタンスの管理方法を指定できます。インスタンスタイプは次の2つがあります。

表3.2 インスタンスタイプ

instance説明
singleton (default) S2Container::getComponent()でコンポーネントを取得すると、常に同じインスタンスが返されます。
prototype S2Container::getComponent()でコンポーネントを取得すると、常に新規インスタンスが返されます。

コメントアノテーションでインスタンスタイプを指定する場合は次のようになります。

<?php
/**
 * @S2Compnent('instance' => 'prototype')
 */
class Service {}

S2Containerの定義ファイルで設定する場合は、次のような内容を記述します。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN"
"http://www.seasar.org/dtd/components21.dtd">
<components>
    <component class="Service" instance="prototype"/>
</components>

3.1.7. ConstructClosureによるコンポーネントの生成

コンポーネントの生成を行う処理をClosureで設定することができます。ConstructClosureの設定は、 s2component関数で行います。

s2component('PDO')
  ->setConstructClosure(function(){
        return new PDO('sqlite:sqlite.db');
    });

setConstructClosureメソッドのAliasとしてconstructメソッドも定義されています。

s2component('PDO')->construct(function(){
    return new PDO('sqlite:sqlite.db');
});

ConstructClosureの戻り値は、s2component関数で指定するクラスとinstanceofの関係を満たす必要があります。
staticなファクトリメソッドなどで生成したインスタンスをコンポーネントとして扱うことができます。

$options = array('dbname' => 'sqlite.db');

s2component('Zend_Db_Adapter_Abstract')
  ->setName('zendPdo')
  ->setConstructClosure(function() use($options) {
        $db = Zend_Db::factory('PDO_SQLITE', $options);
        Zend_Db_Table_Abstract::setDefaultAdapter($db);
        return $db;
    });
[注意]NOTE

このExampleは example/ManualDI/closure にあります。



© Copyright The Seasar Foundation and the others 2005-2010, all rights reserved.