symfony2 service container: inject me, my friend
TRANSCRIPT
Kirill chEbba [email protected]
Symfony Service Container.Inject me, my friend.
Theory
Service Container. Theory
Kirill chEbba Chebunin
•Inversion of Control•Dependency Injection•IoC(DI) Container
Don't call us, we'll call you
Service Container. Theory
Kirill chEbba Chebunin
IoC Implementation
Service Container. Theory
Kirill chEbba Chebunin
•Interfaces•Abstract Factory•Service Locator
Dependency Injection
Service Container. Theory
Kirill chEbba Chebunin
•Constructor Injection•Setter Injection•Interface Injection
IoC Container
Service Container. Theory
Kirill chEbba Chebunin
•Service Definitions•Factory•Service Locator
IoC Container
Service Container. Theory
Kirill chEbba Chebunin
Symfony2 Service Container=
IoC Container
Service Container. Implementation
Kirill chEbba Chebunin
Service Definition
Service Container. Implementation
Kirill chEbba Chebunin
<service id="monolog.logger.event" class="%logger.class%"> <argument>event</argument> <call method="pushHandler"> <argument type="service" id="monolog.handler.main"/> </call> <call method="pushHandler"> <argument type="service" id="monolog.handler.firephp"/> </call> <call method="pushHandler"> <argument type="service" id="monolog.handler.debug"/> </call></service>
Constructor Injection
Service Container. Implementation
Kirill chEbba Chebunin
class IdentityTranslator implements TranslatorInterface{ public function __construct(MessageSelector $selector) {/**/}}
<service id="translator" class="Symfony\Component\Translation\IdentityTranslator"> <argument type="service" id="translator.selector"/></service>
Setter Injection
Service Container. Implementation
Kirill chEbba Chebunin
class Configuration{ public function setSQLLogger(SQLLogger $logger = null) {/**/}}
<service class="Doctrine\DBAL\Configuration"> <call method="setSQLLogger"> <argument type="service" id="doctrine.dbal.logger"/> </call></service>
Dynamic Service Locator
Service Container. Implementation
Kirill chEbba Chebunin
public function some(){ $this->container->get('logger');}
Additional capabilities
Service Container. Implementation
Kirill chEbba Chebunin
•Parameters•Imports•Private & Abstract Services•Aliases•Tags•…
Scopes
Service Container. Implementation
Kirill chEbba Chebunin
•Container•Prototype•Request•Custom
Custom scope
Service Container. Implementation
Kirill chEbba Chebunin
$this->container->enterScope('request'); $this->container->set('request', $request, 'request');
try { $response = parent::handle($request, $type, $catch); } catch (\Exception $e) { $this->container->leaveScope('request');
throw $e; }
$this->container->leaveScope('request');
Advanced Features
Service Container. Advanced
Kirill chEbba Chebunin
Extensions
Service Container. Advanced
Kirill chEbba Chebunin
Extensions
Service Container. Advanced
Kirill chEbba Chebunin
doctrine: dbal: driver: %database_driver% host: %database_host% port: %database_port% dbname: %database_name% user: %database_user% password: %database_password% charset: UTF8
Extensions
Service Container. Advanced
Kirill chEbba Chebunin
interface ExtensionInterface{ /* … */ function load(array $config, ContainerBuilder $container); /* … */}
Container Compiler
Service Container. Advanced
Kirill chEbba Chebunin
•Compiler•PassConfig•Freeze
Compiler Passes
Service Container. Advanced
Kirill chEbba Chebunin
Compiler Pass
Service Container. Advanced
Kirill chEbba Chebunin
interface CompilerPassInterface{ /** * You can modify the container here before * it is dumped to PHP code. * * @param ContainerBuilder $container */ function process(ContainerBuilder $container);}
Compiler Passes
Service Container. Advanced
Kirill chEbba Chebunin
•Merge•BeforeOptimization•Optimization•BeforeRemoving•Removing•AfterRemoving
Optimization Passes
Service Container. Advanced
Kirill chEbba Chebunin
•ResolveParameterPlaceHolders•ResolveReferencesToAliases•CheckCircularReferences•...
Removing Passes
Service Container. Advanced
Kirill chEbba Chebunin
•RemovePrivateAliases•RemoveAbstractDefinitions•ReplaceAliasByActualDefinition•...
Compiler Pass Hooks
Service Container. Advanced
Kirill chEbba Chebunin
•BeforeOptimization•BeforeRemoving•AfterRemoving
MergePassAdd
Extension Services
Service Container. Advanced
Kirill chEbba Chebunin
Frozen Container
Service Container. Advanced
Kirill chEbba Chebunin
Container Dumper
Service Container. Advanced
Kirill chEbba Chebunin
Container Dumper
Service Container. Advanced
Kirill chEbba Chebunin
•XmlDumper•YamlDumper•PhpDumper
appDevDebugProjectContainer
Service Container. Advanced
Kirill chEbba Chebunin
protected function getLoggerService(){ $this->services['logger'] = $instance = new \Symfony\Bridge\Monolog\Logger('app');
$instance->pushHandler($this->get('monolog.handler.main')); $instance->pushHandler($this->get('monolog.handler.firephp')); $instance->pushHandler($this->get('monolog.handler.debug'));
return $instance;}
Container & Bundles
Service Container. Bundles
Kirill chEbba Chebunin
Container & Bundles
Service Container. Bundles
Kirill chEbba Chebunin
•Extension•Compiler Passes•Bundle Boot
Bundle Extension
Service Container. Bundles
Kirill chEbba Chebunin
Bundle Extension
Service Container. Bundles
Kirill chEbba Chebunin
SecurityBundle/Resources/config/templating_php.xml
<services> <service id="templating.helper.security" class="%templating.helper.security.class%"> <tag name="templating.helper" alias="security" /> <argument type="service" id="security.context" on-invalid="ignore" /> </service></services>
Bundle Extension
Service Container. Bundles
Kirill chEbba Chebunin
// load services $loader = new XmlFileLoader( $container, new FileLocator(__DIR__.'/../Resources/config') ); $loader->load('security.xml'); $loader->load('security_listeners.xml'); $loader->load('security_rememberme.xml'); $loader->load('templating_php.xml'); $loader->load('templating_twig.xml'); $loader->load('collectors.xml');
Bundle Compiler Passes
Service Container. Bundles
Kirill chEbba Chebunin
Bundle Compiler Passes
Service Container. Bundles
Kirill chEbba Chebunin
TwigBundle
public function build(ContainerBuilder $container){ parent::build($container);
$container->addCompilerPass( new TwigEnvironmentPass()); $container->addCompilerPass( new ExceptionListenerPass());}
Bundle Compiler Passes
Service Container. Bundles
Kirill chEbba Chebunin
TwigEnvironmentPass
$definition = $container->getDefinition('twig');
foreach ($container->findTaggedServiceIds('twig.extension') as $id => $attributes) {
$definition->addMethodCall('addExtension', array(new Reference($id)));}
Bundle Boot
Service Container. Bundles
Kirill chEbba Chebunin
It is Your Choice
Service Container. Afterword
Kirill chEbba Chebunin
•Constructor VS Setter injection•DI VS Service Locator•Extension VS Compiler Pass
The End
Service Container. Afterword
Kirill chEbba Chebunin
Time for Questions
Service Container. Afterword
Kirill chEbba Chebunin
•[email protected]•http://github.com/chEbba•@iamchEbba