Dependency Injection, Zend Framework and Symfony Container
Upcoming SlideShare
Loading in...5
×
 

Dependency Injection, Zend Framework and Symfony Container

on

  • 3,456 views

Introduction of Dependency Injection pattern, and integration of 'Symfony Injection' component and 'Zend Framework'.

Introduction of Dependency Injection pattern, and integration of 'Symfony Injection' component and 'Zend Framework'.

Statistics

Views

Total Views
3,456
Views on SlideShare
3,456
Embed Views
0

Actions

Likes
2
Downloads
13
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as OpenOffice

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Dependency Injection, Zend Framework and Symfony Container Dependency Injection, Zend Framework and Symfony Container Presentation Transcript

  • Dependency Injection Integration of Symfony DI Container to Zend Framework
  • Who am I ?
    • Diego Lewin
    • Software Architect at www.fishpond.co.nz
    • Technical Director at www.reddelacosta.com.ar
    • Consultant at www.bookfinda.com.au
    • What is a dependency ?
    • What is a dependency
    Product Service class Cache class Loging class EntityManager class 'Object A' dependends on 'Object B' if 'Object A' needs 'Object B' in order to execute correctly. (Jakob Jenkov)
  • More dependencies
    • Chaining dependencies
    Product Service class Cache class Loging class EntityManager class DB Writer class Frontend class Backend class Log Writer class As the size of the applications grows, the amount and complexity of dependencies grows as well
  • Hardcoded Dependencies Make dependencies explicit class ProductService { ... public function __constructor() { $boostrap = Zend_Controller_Front::getInstance()->getParam('bootstrap'); $this->_cache = $boostrap->getResource('cache'); $this->_logger = $boostrap->getResource('logger'); $this->_entityManager = $boostrap->getResource('entityManager'); } } We have hardcoded dependencies when, the class set its dependencies by itself:
  • Dependency Injection ? Make dependencies explicit
    • Inject the dependencies classes from outside through the constructor or setter methods, instead of retrived by the object itself.
    ..... $cache = $boostrap->getResource('cache') $logger = $boostrap->getResource('logger') $entityManager = $boostrap->getResource('entityManager') $productService = new ProductService( $cache, $logger, $entityManager ); Injecting dependencies through the constructor:
  • New Code... Make dependencies explicit class ProductService { ... public function __constructor($cache, $logger, $entityManager) { $this->_cache = $cache; $this->_logger = $logger; $this->_entityManager = $entityManager; } } Injecting dependencies through the constructor:
  • Dependency InjectionTypes
    • Constructor Injection: The dependencies are injected trought the constructor. Advantage is that always when created the object is ready to be used.
    • Setter Injection: The dependencies are injected trought setter, this can be good if a large numbers of dependencies are present.
    • Interface: Components implement specific containers provided by the containers in order to be configured.
  • Dependency Injection
    • Without dependency injection, a consumer component that needs a particular service in order to accomplish a task must create an instance of a class that concretely implements the dependency interface.
    • When using dependency injection, a consumer component specifies the service contract by interface, and the injector component selects an implementation on behalf of the dependent component. (inversion of control)
    • In its simplest implementation, code that creates a dependent object supplies dependencies to that object via constructor arguments or by setting properties on the object.
    • Wikipedia (http://en.wikipedia.org/wiki/Dependency_injection)
  • Advantages
    • Make dependencies explicit: Makes it clear which are the dependencies, we don't have to go trought all the code to see which are the dependencies.
    • Loose Coupling.
    • More Testable code: Unit test, able to replace for Mocks objects.
    • Inject different object for different environments (different logger for dev/production).
    • Since the object creation is handle by a centralized component, we avoid copy paste the same code inside of different objects.
  • Dependency Injection Container DI container The Container knows: - How the create new objects. - Classes Dependencies. Cache Logger EManager ProductService Cache Logger Event Manager An object and its dependencies can be created and initialized by a ”Dependency - Injection Container”.
  • DI Containers in Java
    • Spring
    • Pico
    • Butterfly
    Java example using anotations: @Component public class SomeClass { @Autowired(required=true) public SomeClass(OtherClass bean1, OtherClass bean2) { ... } }
  • PHP and DI containers
    • Symfony Dependency Injection
    • Written by Fabien Potencier, stand alone library http://components.symfony-project.org/ stable version
    • Zend Framework 2 DI Component (Beta 1)
    • Not ready yet, but promising.
    • Symfony Dependency Injection
    • Available Formats:
    - PHP - XML - YAML - INI (only be able to define paramenters, no services)
  • Creating the Container (Boostraping) from http://components.symfony-project.org/ require_once '/PATH/TO/sfServiceContainerAutoloader.php'; sfServiceContainerAutoloader::register(); $sc = new sfServiceContainerBuilder(); $loader = new sfServiceContainerLoaderFileXml($sc); $loader->load('/somewhere/container.xml'); $sc->ipManager From http://components.symfony-project.org/dependency-injection/trunk/book/05-Service-Description
  • Service Definition (XML format) from http://components.symfony-project.org/ <service id=&quot;ipManager&quot; class=&quot;MyLib _Gearman_Client_Competitor_IpManager&quot; > <argument type=&quot;service&quot; id=&quot;documentManager&quot;/> <argument type=&quot;service&quot; id=&quot;gearmanClient&quot;/> <argument type=&quot;service&quot; id=&quot;ipmanager.logger&quot;/> </service> <service id=&quot;ipmanager.logger&quot; class=&quot;MyLib_Log&quot; constructor=&quot;getInstance&quot;> <call method=&quot;addWriter&quot;> <argument type=&quot;service&quot;> <service class=&quot;Zend_Log_Writer_Stream&quot;> <argument>php://output</argument> </service> </argument> </call> <call method=&quot;addWriter&quot;> <argument type=&quot;service&quot;> <service class=&quot;Zend_Log_Writer_Stream&quot;> <argument>%ipmanager.loger.file%</argument> </service> </argument> </call> </service> .... ....
  • Need for Speed from http://components.symfony-project.org/ ..... $phpCointernerClassCode = $dumper->dump(array('class' => 'Container')); file_put_contents('/somewhere/container.php', $code); Symfony DI compoment has a mechanism where optimized 'plain' php container classes can be Generated from configuration. Once generated those containers classes can be used avoiding parsing configuration files every time.
  • Need for Speed from http://components.symfony-project.org/ class SymfonyContainerDev extends sfServiceContainer { protected function getLogerService() { if (isset($this->shared['loger'])) return $this->shared['loger']; $instance = call_user_func(array('MyLib_Log', 'getResource')); return $this->shared['loger'] = $instance; } protected function getIpManagerService() { if (isset($this->shared['ipManager'])) return $this->shared['ipManager']; $instance = new Fishpond_Gearman_Client_Competitor_IpManager( $this->getService('documentManager'), $this->getService('gearmanClient'), $this->getService('ipmanager.logger')); return $this->shared['ipManager'] = $instance; } ...... ..... } The Container Builder use the configuration to create a php container class that is able to create an inject dependencies. The Container class created it is optimized for speed and don't have any overhead (parsing configuration files, etc).
  • Symfony DI - ZF Integration
      Custom_Resource_Symfonycontainer I worte a 'Custom Zend Application Resource' ,to define diferent services we use the container configuration files described in the documentation, and we use the 'application.ini' only to configure the resource itself. You can find the code at: https://github.com/diegol/Sympony-Dependency-Injection-Zend-Framwerok-Resource ): application.ini: [production] resources.symfonycontainer.libraryPath = LIBRARY_PATH &quot;/Symfony/DependencyInjection/&quot; resources.symfonycontainer.configContainerFile = APPLICATION_PATH &quot;/configs/services/sfServices-production.xml&quot; resources.symfonycontainer.dumpFile = APPLICATION_PATH &quot;/Containers/SymfonyContainerDev.php&quot; resources.symfonycontainer.containerClass = &quot;SymfonyContainerDev&quot; resources.symfonycontainer.generateContainerClasses = false [development] resources.symfonycontainer.configContainerFile = APPLICATION_PATH &quot;/configs/services/sfServices-development.xml&quot;
    • resources.symfonycontainer.generateContainerClasses = true
    • Note: Production and development in this example use diferent xml files, in this way we can use different definitions for diffrent enviroments.
  • Symfony DI - ZF Integration
      To use it (not as tidy as Java): $productService = $boostrap->getResource('symfonycontainer') ->getContainerBuilder() ->productService;
  • (byYak_Shaving)
  • Questions ? Thanks..
      You can find the code at: https://github.com/diegol/Sympony-Dependency-Injection-Zend-Framwerok-Resource