TL; DR移動你的服務定義之下自動加載定義在services.yml
並更改WsseFactory
代碼
$container
->setDefinition($providerId, new ChildDefinition(WsseProvider::class))
->setArgument('$userProvider', new Reference($userProvider))
;
充分說明。 所提供的代碼中的第一個錯誤是服務定義預先添加了自動加載行。自動加載只會覆蓋以前的定義,並會導致AuthenticationManagerInterface
失敗。移動下面的定義將解決問題。另一種解決問題的方法是@yceruto和@gintko指向的別名。
但是,只有這一舉動不會使代碼工作,儘管你的答案。你可能沒有注意到如何改變別的東西來使它工作。
第二個問題,replaceArgument
的失敗與正確推測的Symfony容器編譯順序有關。訂單在PassConfig
類中定義:
$this->optimizationPasses = array(array(
new ExtensionCompilerPass(),
new ResolveDefinitionTemplatesPass(),
...
$autowirePass = new AutowirePass(false),
...
));
我省略了不相關的通行證。首先生成由WsseFactory
創建的security.authentication.provider.wsse.wsse_secured
定義。然後ResolveDefinitionTemplatesPass
會發生,並會嘗試更換定義的參數,提高Cannot replace arguments
例外,你有:會出現
foreach ($definition->getArguments() as $k => $v) {
if (is_numeric($k)) {
$def->addArgument($v);
} elseif (0 === strpos($k, 'index_')) {
$def->replaceArgument((int) substr($k, strlen('index_')), $v);
} else {
$def->setArgument($k, $v);
}
}
問題原因的傳球將調用Definition::replaceArgument
爲index_0
。由於父母定義在位置0沒有任何參數,前者services.xml
也沒有固定參數。 AutowirePass
尚未執行,自動生成的定義沒有參數,手動定義僅具有名爲$cachePool
的參數。
因此,要解決這個問題,你可以使用比較:
->setArgument(0, new Reference($userProvider)); //proposed by @yceruto
->replaceArgument('$userProvider', new Reference($userProvider)); //proposed by @gintko
->setArgument('$userProvider', new Reference($userProvider)); // by me
他們都將需要的Definition::addArgument
或Definition::setArgument
的電話,並會制定。只有一點區別: - setArgument(0, ...
無法適用於其他一些場景; - 由於語義,我喜歡->setArgument('$userProvider'
多於->replaceArgument('$userProvider'
。沒有什麼可以替代!
希望詳細說明問題的原因現在清楚了。
PS。還有其他幾個有趣的方法來解決這個問題。
修復配置了一下:
AppBundle\Security\Authentication\Provider\WsseProvider:
arguments:
0: ''
$cachePool: '@cache.app'
public: false
或一組Symfony\Component\Security\Core\User\UserProviderInterface
別名,讓自動裝配爲你做的休息。
$container
->setDefinition($providerId, new ChildDefinition(WsseProvider::class))
// ->replaceArgument(0, new Reference($userProvider))
;
$container
->setAlias('Symfony\Component\Security\Core\User\UserProviderInterface',$userProvider)
;
您是否拉回購回來並嘗試修復?因爲答案中沒有任何內容會影響回購的基本實施。我有一個使用FOS User Bundle的版本,但它不起作用。它已經配置好了。 –
@JakeN:請參閱我的編輯。我已經完全改變了答案。 – tukan