1

I'm trying to implement interface injection with Silex\Application. I have my bootstrapping in one PHP file, mind, this is simplified without the interfaces actually:

$app = new Silex\Application();
$app->register(
    new ServiceProvider($app)
);

$app['testme'] = function() {
    throw new Exception('I am invoked');
};

$app->run();

And I have the ServiceProvider:

class ServiceProvider implements ServiceProviderInterface
{
    public function register(Application $app) {
        foreach ($app as $key => $val) {
            if ($key == 'testme') {
               throw new Exception('it works!');
            }
        }
    }
}

The first exception should not be thrown but I expected the second one to trigger.

Why does the above not work and where might be the spot in silex to inject configuration into interfaces according to $app[....] instanceof MyAwareInterface ?

Daniel W.
  • 31,164
  • 13
  • 93
  • 151
  • 1
    I don't quite understand your question and what you're trying to achieve, so I'll just leave you a comment about why your code doesn't work. You're trying to loop through Pimple (in your code $app) as an array, which is not possible, because Pimple implements ArrayAccess only. If you need such functionality you can extend Pimple and implement Iterator, or IteratorAggregate. – Darko Jan 15 '15 at 15:51
  • Also you need to take care of the order, place $app['testme'] ... first. Then the service Provider can access $app['testme'] – ivoba Feb 06 '15 at 11:44
  • @ivoba Not sure what you mean, but objects/services are lazy loaded through callbacks, so the order is rather unimportant. – Daniel W. Feb 06 '15 at 11:51
  • @DanFromGermany $app->register will be executed directly which will call $provider->register, so the order is relevant here. To quote the docs: "You need to watch out in what order you do certain things when interacting with providers." – ivoba Feb 06 '15 at 12:40

1 Answers1

0

Your exemple updated with Silex's IOC and my poor knowledges about interface injection:

$app = new Silex\Application();

$app->register(
    new ServiceProvider($app)
);

$app['testme'] = function() {
   return new ThisObjectImplementsMyInterface();
};

$app->run();

And I have the ServiceProvider:

class ServiceProvider implements ServiceProviderInterface{
    public function register(Application $app) {
        $app['configure.interface'] = function() use ($app) {
            foreach ($app as $val) {
                if ($val instanceOf 'MyInterface') {
                   $val->configureInterfaceMethod($app['param1'], $app['param2'] /*, ...*/);
                }
            }
        }
    }

    public function boot(Application $app) {
        $app['configure.interface'];
    }
}
Fractaliste
  • 5,777
  • 11
  • 42
  • 86
  • It doesnt matter what I set testme to, it was just an example. How does your answer show where interface injection can be implemented in Silex or how – Daniel W. Jan 15 '15 at 17:54
  • @DanFromGermany Your need is quite unclear, I just update my answer with an exemple of my interpretation of interface injection. – Fractaliste Jan 16 '15 at 08:44
  • Thanks for providing more code. `foreach ($app as $val) {` this point does not work as `Silex\Application` is no traversable. – Daniel W. Jan 16 '15 at 12:06