2017-09-21 6 views
3

を変更し、DIsymfonyの3.3依存性の注入はSynfony 3.3で

のための新たなベストプラクティスは、代わりに $この経由して公共サービスをフェッチする通常のコンストラクタ依存性注入(またはコントローラで「アクション」 インジェクション)を使用することです - > GET()(それはまだ動作しませんが)

as seen in offical documentation

だから私たちはクラスのコントローラでそれらをヒント入力できるようなサービスを指定する必要はありません:

class InvoiceMailer 
{ 
    private $generator; 

    public function __construct(InvoiceGenerator $generator) 
    { 
     $this->generator = $generator 
    } 

    // ... 
} 

これはうまくいくようですが、クラスを拡張してコンストラクタにパラメータを追加するとどうなりますか?

use Symfony\Component\HttpKernel\Exception\HttpException; 

class MyClass extends HttpException 
{ 
    private $generator; 

    public function __construct(InvoiceGenerator $generator, \Exception $previous = null, array $headers = [], $code = 0) 
    { 
     $this->generator = $generator; 
     $statusCode  = $generator->getStatusCode(); 
     $message   = $generator->getTitle(); 

     parent::__construct($statusCode, $message, $previous, $headers, $code); 
    } 

    // ... 
} 

今、私は循環参照エラーが表示されます。

[symfonyの\コンポーネント\依存性の注入\例外の\ ServiceCircularReferenceException]サービス "AppBundle \サービス\ MyClassの"、パスの検出 循環参照:「AppBundle \ Service \ MyClass - > AppBundle \ Service \ MyClass "を選択します。

だから、この場合のベストプラクティスは何ですか?

ありがとうございました。あなたが実際に明示的\Exception $previous引数としてサービスを定義する必要がある場合があり、その場合のために

+0

私が推測しなければならなかったのは、あなたのInvoiceGeneratorが何とかHttpExceptionに依存していると思われます。または、あなたがMyClassを注入しているものであれば、 – Cerad

+1

例外はサービスであってはなりません。 [docs](https://symfony.com/doc/current/service_container/3.3-di-changes.html#controllers-are-registered-as-services)の「exclude」を参照してください。ここには「除外」という設定例があります(https://github.com/Symplify/Symplify/blob/fe457d0bba80033d34b18ca728f8a291e0343ebc/packages/Statie/src/config/services.yml#L8) –

答えて

2

は(HttpException経由)MyClassの親クラスであるので、オートワイヤリング方法は、注入/この引数で再度MyClassのインスタンスを作成し、その結果しよう: " 「循環参照」を参照してください。

これはあなたに何が起こるかを抽象化したものです:

namespace App\Foo; 

class MyClass extends \Exception 
{ 
    public function __construct(\Exception $previous = null) 
    { 
    } 
} 

同じエラー、この引数にnull値を渡し、それを解決することができますので:

# service.yml 
services: 
    # ... 
    App\Foo\MyClass: 
     $previous: ~ 

または手動でその定義を変更コンパイラパスまたはDI拡張で使用します。