Symfony5中如何在私有(非路由)函数中调用Doctrine仓库?
在Symfony5中给控制器私有方法注入仓库的简洁方案
最优方案:构造函数注入仓库
直接在控制器的构造函数中注入仓库实例,将其保存为类属性,这样控制器内所有私有方法都可以直接调用,无需层层传递参数,完全符合Symfony依赖注入的最佳实践:
use App\Repository\ExtraOpeningRepository; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; class YourController extends AbstractController { private $extraOpeningRepository; // 构造函数注入仓库 public function __construct(ExtraOpeningRepository $extraOpeningRepository) { $this->extraOpeningRepository = $extraOpeningRepository; } public function showAction(DebitPeriod $debitPeriod) { $units = 1; $dataset = $this->assembleEntries($units); } private function assembleEntries($units, $day = null) { // 直接使用类属性中的仓库实例 $entries = $this->extraOpeningRepository->findBy(['unit' => $units]); // 后续业务逻辑处理 } }
备选方案:通过容器获取(不推荐)
如果控制器继承了AbstractController,可以直接从服务容器中获取仓库实例,适合快速临时场景,但会降低代码的可测试性:
private function assembleEntries($units, $day = null) { // Symfony 5.x 可直接调用get方法 $extraOpeningRepository = $this->get(ExtraOpeningRepository::class); // Symfony 5.4+ 推荐用container属性 // $extraOpeningRepository = $this->container->get(ExtraOpeningRepository::class); $entries = $extraOpeningRepository->findBy(['unit' => $units]); }
为什么之前的方式会报错
- 方式一直接
new ExtraOpeningRepository()失败:Symfony的实体仓库默认依赖EntityManagerInterface,手动实例化时未传递构造参数,所以触发参数不足的错误。 - 方式二如果调用时不传仓库实例,同样会因为缺少构造参数报错,而你不想层层传参,因此构造函数注入是最合理的解决方式。
内容的提问来源于stack exchange,提问作者Matt Welander
相关产品推荐
相关产品推荐

