プロバイダ束縛

プロバイダ束縛は型に対してそのプロバイダをマッピングします。

$this->bind(TransactionLogInterface::class)->toProvider(DatabaseTransactionLogProvider::class);

プロバイダは ProviderInterface を実装しています。このインターフェイスは値を供給するだけのシンプルなインターフェイスです。

namespace Ray\Di;

interface ProviderInterface
{
    public function get();
}

プロバイダはそれ自身でも依存性を持っており、コンストラクタを介して依存性を受け取ります。
以下の例では ProviderInterface を実装し、型の安全性が保証された値を返します。


use Ray\Di\Di\Inject;
use Ray\Di\ProviderInterface;

class DatabaseTransactionLogProvider implements ProviderInterface
{
    public function __construct(
        private readonly ConnectionInterface $connection)
    ){}

    public function get()
    {
        $transactionLog = new DatabaseTransactionLog;
        $transactionLog->setConnection($this->connection);

        return $transactionLog;
    }
}

最後に toProvider() メソッドを用いてプロバイダを束縛します。

$this->bind(TransactionLogInterface::class)->toProvider(DatabaseTransactionLogProvider::class);

インジェクションポイント

InjectionPointオブジェクトは、注入が行われる箇所(インジェクションポイント)のメタ情報を持つクラスです。プロバイダは、注入箇所のクラス名や変数名などのインジェクションポイントのメタデータを使って依存インスタンスを作成する事ができます。

例:インスタンス生成にインジェクションポイントのクラス名を使用

インジェクションポイントのクラス名を$this->ip->getClass()->getName()で取得して依存インスタンスを生成しています。

class Psr3LoggerProvider implements ProviderInterface
{
    public function __construct(
        private InjectionPointInterface $ip
    ){}

    public function get()
    {
        $logger = new \Monolog\Logger($this->ip->getClass()->getName());
        $logger->pushHandler(new StreamHandler('path/to/your.log', Logger::WARNING));

        return $logger;
    }
}

InjectionPointInterface は以下のメソッドを提供します。

$ip->getClass();      // \ReflectionClass
$ip->getMethod();     // \ReflectionMethod
$ip->getParameter();  // \ReflectionParameter
$ip->getQualifiers(); // (array) $qualifierAnnotations