aura.di

(2016/08/14)
  • 結構人気なPHPDIコンテナ

  • https://github.com/auraphp/Aura.Di
  • コンテナをシリアライズできるっぽい?
  • A serializable dependency injection container with constructor and setter injection, interface and trait awareness, configuration inheritance, and much more.
  • サービスロケータとして使用するなと言ってる

  • 向いてねーぜ!
  • 用意されるゲッターメソッド(get(), newInstance())を使用するとコンテナがロックされる

  • 後から編集不可になる
  • 遅れて何か変更を加えるならlazy*()使え
  • 以下、ドキュメントから読み解いた機能

  • コンストラクタインジェクションとセッターインジェクションをサポート
  • 継承クラスの場合、親クラスのコンストラクタのパラメータにも対応
  • 継承するインターフェース、使用するTraitのセッターメソッドのパラメータにも対応
  • 遅延ローディング
  • Instance factories
  • (オプションで)タイプヒントによる自動インスタンス生成
  • 一番シンプルな使い方
  • php
  • $di = (new ContainerBuilder())->newInstance();
  • $object = $di->newInstance('Vendor\Package\Name');
  • 個人的には好きだけどauraは「古典的だよね☆」って言ってる
  • あるクラスのコンストラクタのパラメータに渡すものを指定する
  • $di->params['Vendor\Package\Example']['foo'] = 'foo_value';
  • 何番目の引数かでも指定可能
  • $di->params['Vendor\Package\Example'][0] = 'foo_value';
  • セッターインジェクション
  • 指定クラスのインスタンスが生成された後に動く
  • setFoo()メソッドに渡す値を定義する
  • $di->setters['Vendor\Package\Example']['setFoo'] = 'foo_value';
  • 継承機能
  • ExampleParentを継承したExampleChildは親の設定を引き継ぐ
  • 下記のように書くとExampleChildにも反映される
  • php
  • $di->params['ExampleParent']['foo'] = 'parent_foo';
  • $di->setters['ExampleParent']['setBar'] = 'parent_bar';
  • ExampleChildに直接設定追加することで設定の上書きも可能
  • php
  • $di->params['ExampleChild']['foo'] = 'child_foo';
  • $di->setters['ExampleChild']['setBaz'] = 'child_baz';
  • Traitのセッターに対して設定が可能
  • $di->setters['ExampleFooTrait']['setFoo'] = 'foo_value';
  • Interfaceのセッターに対しても可能
  • $di->setters['ExampleBarInterface']['setBar'] = 'bar_value';
  • このTraitをuseするとプロパティがセットされる、みたいなの強力な気がする
  • Services
  • key-value形式で遅延ローディング形式でインスタンスをセットできる
  • $di->set('service_name', $di->lazyNew('Example'));
  • ドキュメントを見るにシングルトンになる?
  • 遅延ローディング
  • 必要なタイミングまでインスタンス生成を行わない
  • 下記の例だとExampleクラスに対するアクセスが行われるまでAnotherExampleインスタンスの生成は行われない
  • AnotherExampleのインジェクションにはデフォルトのものが入る
  • $di->params['Example']['foo'] = $di->lazyNew('AnotherExample');
  • 遅延ローディング時のみパラメータを上書きする場合は第二引数に値を渡す
  • 下記の例はbarの値のみ上書きしている
  • $di->params['Example']['foo'] = $di->lazyNew('AnotherExample', ['bar' => 'overriding_bar']);
  • セッターインジェクションの上書きも可能
  • 第三引数で指定する
  • $di->params['Example']['foo'] = $di->lazyNew('AnotherExample', [], ['setBar' => 'overriding_bar']);
  • サービスの遅延ローディングは下記のように指定する
  • $di->set('service_name', $di->lazyNew('Example'));
  • $di->lazyValue()で指定しておくと$di->values()で値を後入れできる
  • include, requireを遅延するための$di->lazyInclude(), $di->lazyRequire()もある
  • イイね!
  • Auto-Resolution
  • 勝手にインスタンス作ってくれる機能
  • みんな楽だから好むけど、デバッグの問題とか考えるとそこまで有利じゃないぜとaura.diは言ってる
  • 使うにはコンテナ作成時に下記のようにする
  • php
  • $container = $builder->newInstance($builder::AUTO_RESOLVE);
  • classのコンストラクタのタイプヒントにしか対応しない
  • arrayのタイプヒントは当然動かない
  • Interfaceでタイプヒントしても無理
  • どの具象クラスが必要かコンテナは分からない
  • 使いたかったらそのInterfaceに対して何を注入するか明示する
  • セッターメソッドも当然使えない
  • aura.diはどのメソッドがセッターメソッドかわからないから当然よね
  • タイプヒントされていたら、かつ設定がなければ全てlayzNew()で捌く
  • ドキュメント
  • コンテナにステージの概念が存在する

  • コンテナにいろいろ突っ込むdefineステージ
  • defineステージが終わるとコンテナがロックされ、編集ができなくなる
  • コンテナから要素を取り出すmodifyステージ
  • use Aura\Di\ContainerConfig;を継承し、defineメソッドとmodifyメソッドでそれぞれのステージでの処理を書ける
  • 上記クラスをまとめて$di = $container_builder->newConfiguredInstance([/** */]);で配列で突っ込める
  • コンテナ定義を階層化、分解できる。最高
  • 雑感

  • APIが洗練されている
  • ベンチ取ってないけどいろいろ記事漁ると高速なのは間違いなさそう
  • 理想と現実で言うところの現実に対して試行錯誤を繰り返してきた感がすごい
  • DI DIコンテナ PHP

general(396)