0

編集

symfony コード、特に ControllerResolver を掘り下げた後、自分で ControllerResolverInterface をサブクラス化/実装しない限り、実際にやろうとしていることはできないようです。

これは、ルートから渡されたコントローラーをインスタンス化する次のコードです。

protected function createController($controller)
{
    if (false === strpos($controller, '::')) {
        throw new \InvalidArgumentException(sprintf('Unable to find controller "%s".', $controller));
    }

    list($class, $method) = explode('::', $controller, 2);

    if (!class_exists($class)) {
        throw new \InvalidArgumentException(sprintf('Class "%s" does not exist.', $class));
    }

    return array(new $class(), $method);
}

最後の行でわかるように、これは常に引数を渡さずにインスタンス化されるため、この方法で何かを注入するには、このメソッドをオーバーライドする必要があります。非常にハッキーな感じです。


元の質問

Symfony コンポーネント (フルスタック フレームワークではないなど)を使用して、動的ルートで定義されたカスタム コントローラーにサービスを挿入する方法を理解しようとしています。

私はフル スタック フレームワークを使用しておらず、DemoBundle src コードも使用していないことに注意してください。composer.jsonコンポーネントを必要とするファイルがあるのでindex.php、ここで詳述されているものとほぼ同じカスタム ファイルがあります。

http://fabien.potencier.org/article/55/create-your-own-framework-on-top-of-the-symfony2-components-part-12

私は次のものを持っています:

$routes = new RouteCollection();
$routes->add(
    'some route name',
    new Route(
      'a route path', 
      array(
        '_controller' => 'App\MyBundle\Controller\MyController::handle'
      )
    )
); 

それから私は内に以下を持っていますApp/MyBundle/DependencyInjection/MyExtension.php:

public function load(array $configs, ContainerBuilder $container) {
    $loader = new XmlFileLoader(
      $container, 
      new FileLocator(__DIR__.'/../Resource/config')
    );
    $loader->load('services.xml');
}

App/MyBundle/Resources/config/services.xml:

<container xmlns="http://symfony.com/schema/dic/services"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://symfony.com/schema/dic/services 
                      http://symfony.com/schema/dic/services/services-1.0.xsd">

<services>
  <service id="templating" class="Symfony\Component\Templating\EngineInterface" />
  <service id="navigation" class="App\MyBundle\Controller\MyController">
    <argument type="service" id="templating" />
  </service> 
</services>
</container>

私は基本的に、テンプレート サービスをMyControllerコンストラクターに注入しようとしています。私の理解では、MyExtensionファイルは自動的に読み込まれる必要があります。私はフルスタックフレームワークを使用していないので、これが理由だと思いますが、どうすればこれを機能させることができますか?

4

2 に答える 2

0

さて、最初に。コントローラーにサービスを挿入する必要はありません。通常のコントローラーが拡張Symfony\Bundle\FrameworkBundle\Controller\Controllerされ、ホール コンテナーが注入されます。templatingこれは、次のようにサービスにアクセスできることを意味します。

public function myAction()
{
    $templating = $this->get('templating');
}

しかし、Symfony2 では、コントローラーをサービスとして作成することもできます。つまり、デフォルトから拡張を削除し、Controller代わりに必要なサービス (通常はrequestresponse) のみを注入します。詳細については、Richard Miller によるこのすばらしい投稿を参照してください。また、Lukas Kahwe Smith によるこの投稿
を 読むこともできます。その中で彼は、サービスが「ベスト プラクティス」であると考える理由について語っています (Symfony プロジェクトの元 Fabien はこれに反対していることに注意してください)。

于 2013-03-27T13:21:15.243 に答える