I have a service provider, that wants to call a method of another service from another provider, that is not yet registered. How can i solve this?
Let's say i have a service $app["two"]
that has a doStuff()
method. Then i have a service $app["one"]
. During registration of $app["one"]
, it's service provider needs to call the $app["two"]->doStuff()
method, but since the provider of $app["two"]
is registered after $app["one"]
, that is impossible since silex doesnt know it yet.
The Provideder of $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();
};
}
}
The registration part of the main app:
$app->register(new OneServiceProvider());
$app->register(new TwoServiceProvider());
In Silex 1, i think there was this extend
method, which could extend/change a service when it is registered. In silex 2, i couldnt find anything similar. Is there any solution to it or should i dispatch an event in $app["two"]
and subscribe to it in $app["one"]
? Or should i use the boot
method to call $app["two"]
?
Update
I just tried the $app->extend approach. Sadly it still threw an error calling member function doStuff() on null
class OneServiceProvider implements ServiceProviderInterface {
public function register(Container $app) {
$app['one'] = function () use ($app) {
$one = new OneService();
$app->extend("two", function($two, $c){
$two->doStuff();
})
return $one;
};
}
}
Solution Since i can no longer reproduce the original issue in clean test code, i'll have to assume that the problem was unrelated. Silex 2 seems to take care of this problem, no matter how you access services during their registration. Tnx for your help anyways!
I think your problem is the lazy call. Don't use this :
$app['one'] = function () use ($app) {
but :
$app['one'] = function (Container $app) {
In the first one, the app don't have provider two.
UPDATE
It's working for me :
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();