PHPixieによる依存性注入コンテナ

画像

私はDIコンテナが好きではありません。 はい、それらは便利ですが、時間の経過とともに多くの問題が発生するため、PHPixieはFactoryパターンで古典的なアプローチを使用します。 コンテナからサービスを取得する機能は、たとえば、一部のバリデーターがSymfony2の完全に異なるバンドルからサービスをプルするときに、プログラムの論理チェーンを壊すことがあります。 さらに悪いことに、 Locator :: get( 'doctrine.entityManager')のスタイルの呼び出しによってすべての依存関係が取得されるService Locatorとして使用される場合。 さらに、さまざまなコンテナの実装により、YMLおよびXMLファイルでの構成の保存が促進され、デバッグが困難になる場合があります。 しかし最近、私は「開発者がばかだとは思わないでください」というフレーズを思い出しました。つまり、あなたの視点をアーキテクチャの開発に押し付けないでください。 さらに、コンテナや依存関係ロケーターを使用して小さなプロジェクトを構築する方がはるかに簡単だと主張することは困難です。



PHPixie DIをご覧ください



フレームワーク自体では使用されていませんが、完全にオプションのコンポーネントとしてデフォルトのバンドルが付属していることに注意してください。 依存関係はないため、PHPixieとは完全に別個に使用できます。



構成



コンテナを構築するには、基本クラスを展開し、その中のconfigureメソッドをオーバーライドする必要があります。次に例を示します。



class Container extends \PHPixie\DI\Container\Root { public function configure() { //     $this->value('apiToken', '1234567890'); //    $this->callback('addFive', function($a, $b) { return $a + $b; }); //      , //      $this->build('twitterService', function() { return new TwitterService($this->apiToken()); //  return new TwitterService($this->get('apiToken')); }); //     : $this->instance('twitterService', TwitterService::class, ['@apiToken']); //      '@'        //   $this->group('user', function() { $this->instance('repository', UserRepository::class, ['@twitterService']); }); } } //   $container = new Container(); //    $container->get('apiToken'); $container->apiToken(); //     //    Container::apiToken(); Container::get('apiToken'); //   //        $container->add(6, 7); // 13 $container->call('add', [6, 7]); $callable = $container->get('add'); $callable(6, 7); //    $container->get('user.repository'); $userGroup = $container->user(); $userGroup->repository(); Container::user()->repository(); // ...
      
      







追加のボーナスとして、コンテナを使用して、クラスのメソッドにアクセスできます。たとえば、 getTweetsメソッドがTwitterServiceクラスに存在する場合、次のようにできます。



 $container->get('twitterService.getTweets'); // $container->twitterService()->getTweets(); //   $container->call('twitterService.getTweets.first.delete', [true]); // $container->twitterService()->getTweets()->first()->delete(true); //     
      
      







ところで、すべてのvaluecallbackbuild、およびinstanceメソッドはprotected と宣言 されています。 したがって、コンテナを構築した後は、何も追加したり変更したりすることはできません。これにより、コンテナをその場で変更して自分自身を撃つ機会から保護されます(デバッグは非常に不快です)。 ただし、外部から設定する必要がある場合は、いつでも公開できます。 ちなみに、「内部のみからの構成」は私のお気に入りの機能の1つです。



IDEのヒント

クラスに注釈を追加して、ほとんどのIDEでメソッド名の入力を求めることができることに注意してください。



 /** * @method TwitterService twitterService() * @method static TwitterService twitterService() */ class Container { //... }
      
      







PHPixieで使用する



バンドルにコンテナクラスを作成します。

 namespace Project\App; //    ,    //     class Container extends \PHPixie\DefaultBundle\Container { public function configure() { //.... parent::configure(); } }
      
      







そして、ビルダーに追加します。

 namespace Project\App; class Builder extends \PHPixie\DefaultBundle\Builder { protected function buildContainer() { return new Container($this); } }
      
      







Builderはコンテナインスタンスを自動的に作成するため、すぐに静的メソッドを安全に使用できます。 さて、いくつかの例:



 $container = $builder->container(); $container->get('components.orm'); $query = $container->call('components.orm.query', ['user']); $builder = Container::builder(); $frameworkBuilder = Container::frameworkBuilder();
      
      







新しいコンポーネントを楽しんで、 「phpixie / di」:「〜3.0」composer.jsonに追加してください。



All Articles