Created
June 28, 2011 11:42
-
-
Save igorw/1050974 to your computer and use it in GitHub Desktop.
Controllers as services with Silex.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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')); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.