Silex 2 - 提供商需要另一项尚未注册的服务

时间:2017-05-29 19:04:04

标签: php silex

我有一个服务提供商,想要从另一个尚未注册的提供商调用另一个服务的方法。我该如何解决这个问题?

假设我有一个$app["two"]方法的服务doStuff()。然后我有一个服务$app["one"]。在注册$app["one"]期间,它的服务提供商需要调用$app["two"]->doStuff()方法,但由于$app["two"]的提供者是在$app["one"]之后注册的,因此这是不可能的,因为silex不知道它爱好。

$app["one"]的提供者:

class OneServiceProvider implements ServiceProviderInterface {

    public function register(Container $app) {

        $app['one'] = function () use ($app) {
            $app['two']->doStuff(); // <- Error since not yet registered!
            return new OneService();
        };
    }
}

主应用程序的注册部分:

$app->register(new OneServiceProvider());
$app->register(new TwoServiceProvider());

在Silex 1中,我认为有这种extend方法,可以在注册时扩展/更改服务。在silex 2中,我找不到类似的东西。有没有解决方案,或者我应该在$app["two"]发送一个事件并在$app["one"]订阅它?或者我应该使用boot方法来调用$app["two"]

更新

我刚尝试了$ app-&gt;扩展方法。可悲的是,它仍然引发了错误calling member function doStuff() on null

类OneServiceProvider实现ServiceProviderInterface {

public function register(Container $app) {

    $app['one'] = function () use ($app) {
        $one = new OneService();
        $app->extend("two", function($two, $c){
            $two->doStuff();
        })
        return $one;
    };
}

}

解决方案 由于我不能再在干净的测试代码中重现原始问题,我将不得不假设问题是无关的。无论您在注册期间如何访问服务,Silex 2似乎都会解决此问题。 Tnx对你的帮助无论如何!

1 个答案:

答案 0 :(得分:1)

我认为你的问题是懒惰的电话。不要用这个:

$app['one'] = function () use ($app) {

但是:

$app['one'] = function (Container $app) {

在第一个应用程序中,应用程序没有提供者2。

<强>更新

它为我工作:

<强> TwoServiceProvider.php

class TwoServiceProvider implements ServiceProviderInterface
{
    public function register(Container $app)
    {
        $app['two'] = function() {
            return new Test();
        };
    }
}

<强> OneServiceProvider.php

class OneServiceProvider implements ServiceProviderInterface
{
    public function register(Container $app)
    {
        $app['one'] = function(Container $app) {
            $app['two']->doStuff();
            return new Test2();
        };
    }
}

<强>的index.php

$app->register(new OneServiceProvider());
$app->register(new TwoServiceProvider());
$app['one']->doStuff();