簡體   English   中英

Symfony3 控制器構造函數注入不起作用

[英]Symfony3 controller constructor injection is not working

我想使用以下代碼將 EntityManager 實例傳遞到我的控制器的構造函數中:

namespace AppBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Doctrine\ORM\EntityManager;

class UserController extends Controller
{

    public function __construct( EntityManager $entityManager )
    {
        // do some stuff with the entityManager
    }
}

我通過將參數放入 service.yml 文件來進行構造函數注入:

parameters:
#    parameter_name: value

services:
#    service_name:
#        class: AppBundle\Directory\ClassName
#        arguments: ["@another_service_name", "plain_value", "%parameter_name%"]
    app.user_controller:
        class: AppBundle\Controller\UserController
        arguments: ['@doctrine.orm.entity_manager']

service.yml 包含在 config.yml 中,當我運行時

php bin/console debug:container app.user_controller

我得到:

 Information for Service "app.user_controller"
 =============================================

 ------------------ ------------------------------------- 
  Option             Value                                
 ------------------ ------------------------------------- 
  Service ID         app.user_controller                  
  Class              AppBundle\Controller\UserController  
  Tags               -                                    
  Public             yes                                  
  Synthetic          no                                   
  Lazy               no                                   
  Shared             yes                                  
  Abstract           no                                   
  Autowired          no                                   
  Autowiring Types   -                                    
 ------------------ ------------------------------------- 

但是,調用映射到我的控制器的路由,我得到:

FatalThrowableError in UserController.php line 17: Type error: Argument 1passed to AppBundle\\Controller\\UserController::__construct() must be an instance of Doctrine\\ORM\\EntityManager, none given, 在 /home/michel/Documents/Terminfinder/ 中調用供應商/symfony/symfony/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php 在線 202

我想不通,為什么 EntityManager 沒有被注入?

當使用基類Controller.phpContainer通常由ControllerResolver的框架自動連接。

基本上,您試圖混淆事物的實際運作方式。

要解決您的問題,您基本上有兩種解決方案:

  1. 不要嘗試注入依賴項,而是直接從您的操作/方法中的容器中獲取它。

public function listUsers(Request $request) { $em = $this->container->get('doctrine.orm.entity_manager'); }

  1. 手動創建控制器但不擴展控制器基類; 並將ip設置為服務

在這一點上更進一步,有些人會建議不要使用 Symfony 提供的默認控制器。

雖然我完全理解他們的觀點,但我在這個問題上稍微溫和一些。

僅注入所需的依賴項背后的想法是避免並強迫人們擁有瘦控制器,這一件好事。

但是,通過一些自動確定,使用現有的快捷方式要簡單得多。

Controller / Action只不過是您的ViewsDomain / Models之間的Models

使用ContainerAware工具防止您在Controller做太多事情。

Controller可以扔掉,而不會在您的系統中產生業務變化。

自 2017 年和 Symfony 3.3+ 起,就有了對控制器作為服務的原生支持。

您可以保持控制器原樣,因為您正確使用了構造函數注入

只需修改您的services.yml

# app/config/services.yml

services:
    _defaults:
        autowire: true

    AppBundle\:
        resouces: ../../src/AppBundle

它會:

  • 將所有控制器和存儲庫加載為服務
  • 自動裝配構造函數依賴項(在您的情況下為EntityManager


更進一步:存儲庫即服務

關於Doctrine + repository + service + controller有很多關於 SO 的問題,所以我已經對一個帖子做了一個一般性的回答 明確檢查您是否更喜歡構造函數注入和服務而不是靜態和服務定位器。

您是否使用以下模式調用控制器AppBundle:Default:index 如果是,那應該是問題所在。 如果您想將控制器用作服務,您必須使用模式: app.controller_id:indexAction ,它使用服務的 id 來加載控制器。

否則,它將嘗試在不使用服務容器的情況下創建類的實例。

有關更多信息,請參閱有關此主題的 symfony 文檔https://symfony.com/doc/current/controller/service.html

實體管理器在控制器中可用,無需注入。 只需要:

$em = $this->getDoctrine()->getManager();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM