3

Symfony コンポーネントの上に独自のフレームワークを作成する方法について、Fabien Potiencier のチュートリアルに従いました。今、私は方法が必要です。そして、すべてのコントローラーをサービスとして定義せずに、依存関係コンテナーをすべてのコントローラーに注入したいと考えています。

元の Symfony2 フレームワークでは、すべてのコントローラーが次の場所にあるControllerクラスを拡張しSymfony\Bundle\FrameworkBundle\Controller\Controller.phpます。

namespace Symfony\Bundle\FrameworkBundle\Controller;

class Controller extends ContainerAware
{
   // ...
}

Controllerクラスはクラスを拡張するためControllerAware、コントローラーで次のようなことができます。

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class MyController extends Controller
{
   public function someAction()
   {
      $this->container->get('dependencie_xyz);
   }
}

私の質問は次のとおりです。フレームワークで同じことをどのように達成できますか?

4

4 に答える 4

3

しばらく時間がかかりましたが、Symfony2 フレームワークがどのようにそれを行うのかがようやくわかりました。SymfonyFrameworkBundle には、解決されたコントローラーで setContainer メソッドを呼び出すカスタム ControllerResolver があります。コントローラーは、ContainerAwareInterface のインスタンスである必要があります。

簡易版:

class ContainerAwareControllerResolver extends ControllerResolver
{
    private $container;

    public __construct(ContainerInterface $container)
    {
        $this->container = $container;
            parent::__construct();
    }

    public function getController(Request $request)
    {
        $controller = parent::getController($request);
        if($controller instanceof ContainerAware ){
            $controller->setContainer($this->container);
        }
    }
}

ソース:

https://github.com/symfony/symfony/blob/master/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerResolver.php

于 2013-03-12T15:53:58.747 に答える
0

コントローラーにインターフェイスを実装していない場合は、この方法で追加でき、機能します。これは、c4pone の実装に対する小さな変更です。

/**
* Description of ContainerAwareControllerResolver
*
* @author sbc
*/
use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpKernel\Controller\ControllerResolver;

class ContainerAwareControllerResolver extends ControllerResolver {

private $container;

public function __construct(LoggerInterface $logger = null, ContainerInterface $container = null) {

    parent::__construct($logger);

    $this->container = $container;
}

protected function instantiateController($class) {

    $new_class = new $class();

    $new_class->setContainer($this->container);

    return $new_class;
}
于 2016-03-18T07:57:29.360 に答える
0

それは単純すぎる。次のコードが役立ちます

namespace Symfony\Bundle\FrameworkBundle\Controller;

use Symfony\Component\DependencyInjection\ContainerInterface as Container;
use Symfony\Component\DependencyInjection\ContainerAware as ContainerAware;

class TestService extends ContainerAware
{
   public function __construct(Container $container) {
      // in your example from official doc 'dependencie_xyz' is a name of service
      $this->setContainer($container); // call parent setContainer() method, for identifying container variable, from now you can access to ServiceContainer using $this->container variable
      $test_param = $this->container->getParameter('test_param'); // get test_param from config.yml
   }

}

service.yml で

このように書いてください

services:
    test_service:
        class: Symfony\Bundle\FrameworkBundle\TestService
        arguments: ['@service_container']

引数としてサービスコンテナーを投稿します

于 2013-09-02T12:10:47.030 に答える
-1

Controller クラスは ControllerAware クラスを拡張するため、Controller で次のようなことができます。

まあ、これは真実ではありません。classのシグネチャContainerAwareを見るとsetContainer、コンテナを設定できるようにメソッドが追加されていることがわかります。Symfony2 は、Controller::get一部のライブを簡単にするメソッドを作成しました。

ソースコードで彼らがどのようにそれを行うかを見ることができます:

/**
 * Gets a service by id.
 *
 * @param string $id The service id
 *
 * @return object The service
 */
public function get($id)
{
    return $this->container->get($id);
}

これを独自のControllerクラスに配置して、すべてのコントローラーにそのコントローラー クラスを拡張させることができます。

于 2013-02-18T19:15:16.733 に答える