Stephan Hochdörfer // 21.02.2014
IoC is a good idea. Like all good ideas, it should be used with moderation.
— Uncle Bob Martin (@unclebobmartin) 5. März 2013
class MyController { public function myAction() { return new Response('Ok!'); } }
class MyController { protected $service; public function __construct(MyService $service) { $this->service = $service; } public function myAction() { $this->service->doSomething(); return new Response('Ok!'); } }
class MyController { protected $service; protected $logger; public function __construct(MyService $service, MyLogger $logger) { $this->service = $service; $this->logger = $logger; } public function myAction() { $this->logger->debug('myAction running'); $this->service->doSomething(); return new Response('Ok!'); } }
class MyController { protected $service; protected $logger; public function __construct(Container $container) { $this->service = $container->get('service'); $this->logger = $container->get('logger'); } public function myAction() { $this->logger->debug('myAction running'); $this->service->doSomething(); return new Response('Ok!'); } }
class MyController implements ContainerAware { protected $service; protected $logger; public function setContainer(Container $container) { $this->service = $container->get('service'); $this->logger = $container->get('logger'); } public function myAction() { $this->logger->debug('myAction running'); $this->service->doSomething(); return new Response('Ok!'); } }
ContainerAware is the new Singleton. #php
— Tobias Schlitt (@tobySen) 14. September 2013
class UserController { protected $auth; protected $user; public function __construct(AuthService $auth, UserService $user) { $this->auth = $auth; $this->user = $user; } public function authAction(Request $r) { return $this->auth->login($r->get('user'), $r->get('pass')); } public function listUserAction() { return $this->user->readAll(); } }
class AuthController { // [...] public function authAction(Request $r) { return $this->auth->login($r->get('user'), $r->get('pass')); } } class UserController { // [...] public function listUserAction() { return $this->user->readAll(); } }
class LoginController { protected $auth; public function __construct(AuthService $auth) { $this->auth = $auth; } public function authAction(Request $r) { return $this->auth->login($r->get('user'), $r->get('pass')); } }
class LoginController { protected $auth; public function __construct(AuthInterface $auth) { $this->auth = $auth; } public function authAction(Request $r) { return $this->auth->login($r->get('user'), $r->get('pass')); } }
@jclermont Funny enough, @shochdoerfer has already suggested that more than once.
— weierophinney (@mwop) 20. Dezember 2013
class UserController { /** * @var Logger * @Inject */ public $logger; public function authAction(Request $r) { if (null !== $this->logger) { $this->logger->debug('Auth action running...'); } } }
class UserController { /** * @var Logger * @Inject */ protected $logger; public function authAction(Request $r) { if (null !== $this->logger) { $this->logger->debug('Auth action running...'); } } }
class UserController { protected $auth; public function __construct(AuthInterface $auth) { $this->auth = $auth; } }
class UserController { protected $logger; public function setLogger(Logger $logger) { $this->logger = $logger; } public function authAction(Request $r) { if (null !== $this->logger) { $this->logger->debug('Auth action running...'); } } }
class UserController { protected $logger; public function setLogger(Logger $logger) { $this->logger = $logger; } public function authAction(Request $r) { if ($this->logger instanceof Logger) { $this->logger->debug('Auth action running...'); } } }
class UserService { protected $auth; public function __construct(AuthInterface $auth) { $this->auth = $auth; } } class SimpleAuthService implements AuthInterface { protected $userService; public function __construct(UserService $userService) { $this->userService = $userService; } }
class UserService { protected $auth; public function __construct(AuthInterface $auth) { $this->auth = $auth; } } class SimpleAuthService implements AuthInterface { protected $userService; public function setUserService(UserService $userService) { $this->userService = $userService; } }
interface LoggerAware { public function setLogger(Logger $logger); }
class UserController implements LoggerAware { protected $logger; public function setLogger(Logger $logger) { $this->logger = $logger; } public function authAction(Request $r) { if (null !== $this->logger) { $this->logger->debug('Auth action running...'); } } }
class AuthService implements AuthInterface { protected $provider; public function __construct(AuthProviderInterface $provider) { $this->provider = $provider; } }
class AuthService implements AuthInterface { protected $provider; public function __construct(AuthProviderInterface $provider) { $this->provider = $provider; } public static function getInstance() { return new AuthService(new DatabaseAuthProvider()); } }
class AuthService implements AuthInterface { protected $provider; public function __construct(AuthProviderInterface $provider) { $this->provider = $provider; } }
class AuthServiceFactory { public static function getInstance() { return new AuthService(new DatabaseAuthProvider()); } }
What is the difference?
interface MyServiceLocator { /** * Returns an entry of the container by its $id. * * @param string $id * @throws NotFoundException * @return mixed */ public function get($id); /** * Returns true if the container can return an entry * for the given identifier. Returns false otherwise. * * @param string $id * @return bool */ public function has($id); }
interface MyDependencyContainer { /** * Returns an entry of the container by its $id. * * @param string $id * @throws NotFoundException * @return mixed */ public function get($id); /** * Returns true if the container can return an entry * for the given identifier. Returns false otherwise. * * @param string $id * @return bool */ public function has($id); }
Push vs. Pull
class MyController { protected $service; protected $logger; public function __construct(MyServiceLocator $locator) { $this->service = $locator->get('service'); $this->logger = $locator->get('logger'); } }
class MyController { protected $service; protected $logger; public function __construct(MyService $service, MyLogger $logger) { $this->service = $service; $this->logger = $logger; } }
internal Configuration
vs.
external Configuration
class AuthService implements AuthInterface { protected $provider; /** * @Inject */ public function __construct(AuthProviderInterface $provider) { $this->provider = $provider; } }
class AuthService implements AuthInterface { protected $provider; /** * @Inject * @Named('RESTAuthProvider') */ public function __construct(AuthProviderInterface $provider) { $this->provider = $provider; } }
/** * @ImplementedBy(RESTAuthProvider) */ interface AuthProviderInterface { /** * Tries to authenticate the user. * * @return bool */ public function authenticate($username, $password); }
services:
authprovider:
class: RESTAuthProvider
authservice:
class: AuthService
arguments: ["@authprovider"]
services:
provider_rest:
class: RESTAuthProvider
provider_soap:
class: SoapAuthProvider
authservice_rest:
class: AuthService
arguments: ["@provider_rest"]
authservice_soap:
class: AuthService
arguments: ["@provider_soap"]
$dep = new \Di\Definition\Builder\PhpClass(); $dep->setName('RESTAuthProvider'); $class = new \Di\Definition\Builder\PhpClass(); $class->setName('AuthService'); $im = new \Di\Definition\Builder\InjectionMethod(); $im->setName('__construct'); $im->addParameter('provider', 'RESTAuthProvider'); $class->addInjectionMethod($im); $builder = new \Di\Definition\BuilderDefinition(); $builder->addClass($dep); $builder->addClass($class); $defList = new \Di\DefinitionList($builder); $di = new \Di\DiContainer($defList);
new AuthService(new RESTAuthProvider());
Thank you!
Do not forget to rate the talk:
https://joind.in/10687
http://www.flickr.com/photos/andresrueda/3452940751/
http://www.flickr.com/photos/andresrueda/3455410635/
http://tchaikovskycf.deviantart.com/
http://sxc.hu