2016-10-02 25 views
1

そのサービスのメソッドが呼び出されると、Symfonyサービスが開始されている(コンストラクタが実行されている)ことに気づきました。これは、サービスにコンストラクタのみがあり、メソッドがない場合には重要です。例えばsymfonyサービスはメソッド呼び出しの後にのみ開始されます

:この場合

class MyService { 

    public function __construct($someOtherService) { 

     $someOtherService->setFoo("bar"); 

    } 
} 

// And of course put this service in services.yml 

app.my_service: 
    class: AppBundle\...\MyService 
    arguments: [ app.some_other_service ] 

、従ってコンストラクタおよびsetFoo( "バー")と呼ばれていません。どうしてこれなの?このサービスで(ダミー)メソッドを呼び出すことなく、何らかの形でサービスを開始することは可能ですか?

また、app.my_serviceに「lazy:false」を追加しようとしましたが、違いはありません。

私はSymfony 2.8を使用しています。

+0

あなたは何かを間違って解釈しています。コンテナからサービスを取得するとすぐにコンストラクタが呼び出されます。単にservices.ymlでサービスを定義しても、サービスがインスタンス化されるわけではありません。 – Cerad

+0

はい、私は今理解しています。そして私はコンテナからそれを得ることなくサービスをロードしたかったのです。 – BigJ

答えて

3

あなたのサービスは決して使用されない場合、インスタンス化されません。インスタンス化サービスを実施するには、サービスを取得する(たとえばkernel.request)必要がある場合に、イベントに適した任意の種類のイベントリスナーに接続し、このサービスをリスナーへの依存として渡すことができます。これは、コンテナの寿命期間中にイベントがトリガされる最初にサービスコンストラクタをトリガします。

しかし、私はむしろアーキテクチャをレビューすることをお勧めしたいと思います。コンストラクタとなるサービスは、あなたが発射イベントなしEvendDispatcher(それはあなたのサービスに依存するであろうという理由だけで)のインスタンス化にサービスをインスタンス化することができ、またナンセンス

ある

リスナーサンプル:

class ServiceInstantiatorListener 
{ 
    public function onRequest(KernelEvent $kernel) 
    { 
    return; //noop, just make sure it works 
    } 

    public function instantiate($service) 
    { 
    return $service; // noop again, just call to pass service container argument 
    } 
} 

YAML config:

services: 
    my_app.service_instantiator_listener: 
    class: My\App\ServiceInstantiatorListener 
    tags: 
    - { 'name': 'kernel_events', 'event': 'kernel.request', 'method':'onRequest' } 
    calls: 
    - [instantiate, ["@my_app.weird_service_one"]] 
    - [instantiate, ["@my_app.weird_service_two"]] 

さらに、タグでサービスをマークし、コールを動的に設定することができますMyAppBundleExtensionコンパイラは

http://symfony.com/doc/current/service_container/tags.html#create-a-compiler-pass

を渡すと、私はインスタンス化するサービス(すなわち、いくつかのコンテナの内部イベント)を強制するためのより良い方法がある願っていますが、現在、私は私がそれを必要とする場合を満たしていません。

+0

はい!私は既に解決策を見つけるためにイベントリスナーを使用することを検討していました。私はあなたが何を意味しているのか理解しており、通常このようなサービスは使用しませんが、これは最悪のケースです。 – BigJ

+0

@BigJ、いくつかのサンプルで投稿を更新しました – ScayTrase

+0

ありがとう、私はあなたの例を使ってそれを行いました。私は "インスタンス化"を使用しませんでしたが、引数としてサービスコンテナを与え、リスナーで2つの奇妙なサービスの両方を呼び出しました;) – BigJ

1

遅延ロードされたサービスの動作について説明します。設定を確認してlazy: trueを削除し、無効にします。

Symfony docs, lazy loaded service:

実際のクラスはすぐにあなたが(例えば、そのメソッドの1つを呼び出す)サービスと対話しようとしてインスタンス化されます。

+0

はい、私はapp.my_serviceに "lazy:false"を追加しようとしましたが、動作しませんでした。私は私のポストにそれを追加します。 – BigJ

1

サービスを開始するには、実際にダミーメソッドを呼び出す必要はありません。 サービスオブジェクトをインスタンス化するには、次のステートメントを使用します。

$ this-> container() - > get( 'app.my_service');

+0

私は知っていた、私はその呼び出しなしでロードするサービスをしたかった。 – BigJ

関連する問題