Sonata 管理控制器 + 依赖注入

Posted

技术标签:

【中文标题】Sonata 管理控制器 + 依赖注入【英文标题】:Sonata admin controller + dependency injection 【发布时间】:2018-04-16 02:20:41 【问题描述】:

我正在为奏鸣曲管理和依赖注入而苦苦挣扎。我定义了一个 Admin 类并为它使用了一个扩展 CRUDController 的控制器。

在这个控制器中我必须做一个 HTTP 请求,所以我想注入一个 Zend HTTP 客户端实例。

news.controller:
    class: MyBundle\Controller\NewsController
    arguments: ['@zend.httpclient']

news.admin
    class: MyBundle\Admin\NewsAdmin
    ...
    arguments:
       - null
       - MyBundle\Entity\News
       - MyBundle:News

新闻控制器的参数永远不会被注入..我认为这是因为管理员不关心我的自定义控制器作为服务。

所以我认为我必须用我定义为“news.controller”的控制器容器服务中的 id 替换直接类名作为管理服务的第三个参数。现在看起来像

news.admin
    class: MyBundle\Admin\NewsAdmin
    ...
    arguments:
       - null
       - MyBundle\Entity\News
       - news.controller

现在我明白了

Call to a member function has() on null

我想,一定是缺少一些配置……怎么了?

有人知道如何将东西注入自定义 CRUDController 并与奏鸣曲管理员一起使用吗?或者我怎么能以另一种方式做到这一点?我需要 CRUDController 因为我为来自自定义模板的多个 AJAX 调用定义了一个 api ...所以还需要一个在 CRUDController 中定义的 entitymanager ...

我还读到将控制器定义为服务并不是最好的方法......但是如果我真的需要它们,那么使用 zend 客户端等外部客户端进行例如 http 调用的正确方法是什么?

【问题讨论】:

好的部分是 has 方法表明您的控制器被定义为服务。但是容器没有被注入。添加调用:[['setContainer', ['@service_container']]] 到你的控制器服务定义 嘿,Cerad,成功了!创建一个答案并将其作为解决方案投票。谢谢! 【参考方案1】:

has() 错误表明,虽然您的控制器现在已正确连接为服务,但尚未注入容器。这种注入通常由控制器解析器在它创建一个新的控制器类之后完成。但是,从容器中拉出控制器时,不会执行此步骤。

解决方案是通过您的服务定义注入容器:

news.controller:
    class: MyBundle\Controller\NewsController
    arguments: ['@zend.httpclient']
    calls:[['setContainer', ['@service_container']]]

很多括号,但是很好。

【讨论】:

我必须将控制器标记为tags: ['controller.service_arguments']。我的错误不是Call to a member function has() on null,而是找不到控制器。

以上是关于Sonata 管理控制器 + 依赖注入的主要内容,如果未能解决你的问题,请参考以下文章

Spring控制反转&依赖注入

Spring依赖注入浅析

深层理解Spring 控制反转和依赖注入,这一篇文够了

控制反转和依赖注入的关系总结

SpringIoc依赖注入依赖反转

javaweb-控制反转与依赖注入