1 回答

TA貢獻1801條經驗 獲得超8個贊
請注意,此答案已使用新信息再次更新。
標簽controller.service_arguments
只需要允許動作注入。堅持使用構造函數注入,__invoke()
這就是您所需要的。
下面的公共添加是一項要求,但事實證明您不需要編譯器傳遞,它可以在 services.yaml 級別完成。因此,您唯一需要的是以下內容:
services: _defaults: autowire: true autoconfigure: true public: true // <---- This is the new additional config.
然后,任何類都可以用作routes.yaml
控制器并且構造注入工作得很好。
注:原答案如下。感謝 Jakumi 為我指明了正確的方向。
您需要添加一個編譯器傳遞來做兩件事。在啟動和注冊自動依賴注入的東西時,如果一個類的Controller
名稱中有:
添加標簽
controller.service_arguments
,這是您通常需要手動添加的標簽services.yaml
以允許 setter 注入(如果您不關心 setter 注入,可以忽略它)將類設置為公共的,因為 Symfony 有一個奇怪的想法,即公共或私有的概念不能從類訪問修飾符中推斷出來(真的嗎?)——這是重要的事情,因為 Symfony 會抱怨控制器是私有的,否則
不要忘記您不必使用“名稱控制器”的邏輯。它可以是“Controller”在類名的末尾,這可能更好。
不管怎樣,先創建一個CompilerPass
. 把它放在任何你想要的地方。我把我的放在旁邊Kernel.php
。
use Symfony\Component\DependencyInjection\{Compiler\CompilerPassInterface, ContainerBuilder};
class ControllersAsServices implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
foreach ($container->getDefinitions() as $definition) {
if (strpos($definition->getClass(), "Controller") === false) {
continue;
}
$definition->addTag("controller.service_arguments");
$definition->setPublic(true);
}
}
}
然后在你的Kernel.php,你需要告訴它使用這個新的。覆蓋受保護的函數build并添加您的編譯器傳遞,如文檔所示:
protected function build(ContainerBuilder $container)
{
$container->addCompilerPass(new ControllersAsServices, PassConfig::TYPE_BEFORE_OPTIMIZATION, -1);
parent::build($container);
}
清除您的開發緩存。在我這樣做之前,我沒有任何改變。
現在,任何Controller名稱中帶有的類都可以像最初那樣被自動裝配。
下面是來自 Jakumi 的原始答案:
我相信在你的情況下最好的方法是實現一個 CompilerPass,將類添加到容器中:
https://symfony.com/doc/current/bundles/extension.html#adding-classes-to-compile
在此過程中,可能還有一種方法可以添加標簽。
Symfony 通過RegisterControllerArgumentLocatorsPass迎合 controller.service_arguments 標簽,它解析構造函數參數并檢查一些特征。如果你讓你的編譯器傳遞優先級更高,那么你可能很容易解決這個問題......
- 1 回答
- 0 關注
- 127 瀏覽
添加回答
舉報