-
-
Save igorw/1050974 to your computer and use it in GitHub Desktop.
<?php | |
class LazyServiceController | |
{ | |
private $container; | |
private $serviceName; | |
public function __construct(\Pimple $container, $serviceName) | |
{ | |
$this->container = $container; | |
$this->serviceName = $serviceName; | |
} | |
public function __invoke() | |
{ | |
call_user_func($this->container[$this->serviceName], func_get_args()); | |
} | |
} | |
class MyController | |
{ | |
private $someService; | |
public function __construct(SomeService $someService) | |
{ | |
$this->someService = $someService; | |
} | |
public function __invoke($name) | |
{ | |
return $this->someService->translateName($name); | |
} | |
} | |
$app = new Silex\Application(); | |
$app['some_service'] = function () { | |
return new SomeService(); | |
}; | |
$app['my_controller'] = function ($app) { | |
return new MyController($app['some_service']); | |
}; | |
$app->get('/{name}', new LazyServiceController($app, 'my_controller')); |
Good question. :)
Well, the point of doing this in general is not having to inject the DI container into your controllers (instead, you inject the dependencies into the controller directly). Thus the controller no longer depends on the container.
Good: You get added flexibility. You no longer hard-code which services to use into your controller. You can specify that in the DI configuration instead. Example: You inject a UserProvider into the UserController for /profile
, but inject a FacebookUserProvider into the same UserController for /profile/facebook
.
Bad: You must manually configure your dependencies in the DIC config. You need to manually assign the injected dependencies. Optional dependencies are no longer lazy-loaded.
Now, I don't really think it makes sense to do this with Silex. Silex is a micro-framework, always injecting the container is perfectly acceptable. If you want code that is decoupled, extract that into a separate library
and integrate it with your app using autoloading and pimple.
This was basically just a proof of concept to show how it could be done.
What's the idea here? I mean. Why would I wrap a controller into a service?