2

メソッド内からサービス (doctrine、twig など) にアクセスする方法を知りたいBundle->build(ContainerBuilder)です。

基本的に、問題は、バンドルがメニュー項目をどこかにハードコードする必要なく、メニュー項目を追加できるメニュー システムが必要なことです。そのために、サービス ベースのメニューが適切に機能すると考えました (そのため、コントローラーでテスト目的で機能するメニュー ビルダー サービスを作成しました)。

私が知る限り、コントローラーは必要なときにのみ読み込まれるため、コントローラーでそれを行うことはできません。コントローラーが使用されているかどうかに関係なく、メニュー項目を追加する必要がある複数のバンドルがあるためです。実際、サイト ナビゲーションに使用されていない場合、メニュー項目はより重要になります。

おそらく Bundle->build メソッドと関係があると思いました。サービスを取得できるようにするContainerBuilder->get必要があるようですが、その中には service_container サービスしかありません (getServiceIds で示されているように)。IContainerBuilder->get('service_container')->getServiceIdsの場合、サービスは service_container だけです。

私の考えでは、バンドルが「構築」されると、サービスはロードされません。

足りないものはありますか?オーバーライド可能なメソッド、リッスンするイベントはありますか?

4

1 に答える 1

5

これは、Symfony のイベント リスナー/ディスパッチ コンポーネントの完璧な使用例です。

バンドル初期化メソッドのように、サービス コンテナーからアイテムが属していない場所にアイテムを渡そうとするのではなく、メニュー ビルダー クラスが Symfony の event_dispatcher サービスを使用してイベントを送信するようにします。メニューを作成するときは、@event_dispatcherサービスを依存関係として追加するだけです。

services:
    acme_bundle.menu_builder:
        class: Acme\AcmeBundle\Menu\MenuBuilder
        arguments: [@event_dispatcher]

次に、MenuBuilder クラスで、EventDispatcher を使用してイベントを送信します。

class MenuBuilder
{
    private $dispatcher;

    public function __construct(EventDispatcherInterface $dispatcher)
    {
        $this->dispatcher = $dispatcher;
    }

    /**
     * Main function for building menus and dispatching related events.
     */
    public function buildMenu()
    {
        $menu = new Menu();
        $event = new MenuEvent('acme_bundle.event_name', $menu);
        $this->dispatcher->dispatch($event);

        return $menu;
    }
}

他のバンドルは、リスナーとしてイベントに登録し、メニュー項目をメニューに追加できます。

services:
    acme_bundle.configure_menu_listener:
        class: Acme\OtherBundle\Listener\ConfigureMenuListener
        tags:
            - { name: kernel.event_listener, event: 'acme_bundle.event_name', method: configureMenu }
于 2012-08-18T03:09:43.463 に答える