SlideShare a Scribd company logo
Dependency
Adding
Injection To Legacy
    Applications
Adding Dependency Injection to Legacy Applications
Who Is i3logix?
Inversion of Control
Dependency Injection
Adding Dependency Injection to Legacy Applications
Adding Dependency Injection to Legacy Applications
Built-In
Flexibility
interface Calc {
    public function __invoke($left, $right);
}

class AddCalc implements Calc {
    public function __invoke($left, $right) {
        return $left + $right;
    }
}

class SubCalc implements Calc {
    public function __invoke($left, $right) {
        return $left - $right;
    }
}
class Calculator{
    public function __invoke(Calc $calc, $left, $right){
        return $calc($left, $right);
    }
}

$calculator = new Calculator();
echo $calculator(new AddCalc(), 2, 1), "n";
echo $calculator(new SubCalc(), 2, 1), "n";
De-Coupling
Have Clear Goals
Adding Dependency Injection to Legacy Applications
It’s
only
  a
Tool
I   T
N   E
J   C
    H
E
    N
C
    I
T
    Q
I
    U
O
    E
N   S
Adding Dependency Injection to Legacy Applications
class Status {
    public function get($system) {
        $client = new Zend_Http_Client();
        $r = $client->setUri(SERVICE_URI)
            ->setParameterGet(compact('system'))
            ->request('GET');

        if ($r->isSuccessful()) {
            return $r->getBody();
        }
        return false;
    }
}
Constructor
   Injection
      Vs.
Setter/Property
   Injection
class StatusSetterInject{
    protected $client;

    public function setClient(Zend_Http_Client $client){
        $this->client = $client;
    }

    public function get($system){
        $r = $this->client->setUri(SERVICE_URI)
            ->setParameterGet(compact('system'))
            ->request('GET');

        if ($r->isSuccessful()){
            return $r->getBody();
        }
        return false;
    }
}
class StatusConstructInject{
    protected $client;

    public function __construct(Zend_Http_Client $client){
        $this->client = $client;
    }

    public function get($system){
        $r = $this->client->setUri(SERVICE_URI)
            ->setParameterGet(compact('system'))
            ->request('GET');

        if($r->isSuccessful()){
            return $r->getBody();
        }
        return false;
    }
}
Init Pattern
class StatusInit{
    protected $client;

   public function __construct(Zend_Http_Client $client){
       $this->client = $client;
       $this->init();
   }

   public function init(){
       //Left empty
   }

    public function get($system){
        $r = $this->client->setUri(SERVICE_URI)
            ->setParameterGet(compact('system'))
            ->request('GET');
//...
    }
}
Optional
Injection
class StatusConstructInjectOptional{
    protected $client;

   public function __construct(
       Zend_Http_Client $client = null){
       if($client === null){
           $client = new Zend_Http_Client();
       }
       $this->client = $client;
   }

    public function get($system){
        $r = $this->client->setUri(SERVICE_URI)
            ->setParameterGet(compact('system'))
            ->request('GET');
//...
    }
}
class StatusSetterInjectOptional{
    protected $client;

   public function setClient(Zend_Http_Client $client){
       $this->client = $client;
   }

   protected function getClient(){
       if ($this->client === null){
           $this->client = new Zend_Http_Client();
       }
       return $this->client;
   }

    public function get($system){
        $r = $this->getClient()->setUri(SERVICE_URI)
            ->setParameterGet(compact('system'))
            ->request('GET');
//...
Class Name Override
class StatusClassNameOverrideConstruct{
    protected $clientClass;

    public function __construct($class = 'Zend_Http_Client'){
        $this->clientClass = $class;
    }

    public function get($system){
        $client = new $this->clientClass;
        $r = $this->getClient()->setUri(SERVICE_URI)
            ->setParameterGet(compact('system'))
            ->request('GET');

        if($r->isSuccessful()){
            return $r->getBody();
        }
        return false;
    }
}
class StatusClassNameOverrideSetter{
    protected $clientClass = 'Zend_Http_Client';

    public function setClass($class){
        $this->clientClass = $class;
    }

    public function get($system){
        $client = new $this->clientClass;
        $r = $this->getClient()->setUri(SERVICE_URI)
            ->setParameterGet(compact('system'))
            ->request('GET');

        if($r->isSuccessful()){
            return $r->getBody();
        }
        return false;
    }
}
BUT I NEED TO CREATE OBJECTS?
class PolyBad {
    public function foo($bar) {
        if (get_class($bar) === 'SomeOtherClass') {
            $tmp = new SomeClass();
        }
    }
}
class PolyGood {
    public function foo(SomeClass $bar) {
        if ($baz instanceof SomeInterface) {
            // Do something
        }
    }
}
Adding Dependency Injection to Legacy Applications
class Factory{
    public function create(){
        return new SimpleClass();
    }
}
Dynamic Factory
abstract class FactoryAbstract{
    protected abstract function getClassName();

    public function create(){
        $class = $this->getClassName();
        $argList = func_get_args();
        if (count($argList) < 1){
            return new $class;
        }
        $rClass = new ReflectionClass($class);
        return $rClass->newInstanceArgs($argList);
    }
}
function __autoload($class){
    $classPath = str_replace('_', '/', $class);
    $filePath = __DIR__."/src/$classPath.php";

    if (file_exists($filePath))
       return require $filePath;

    if (substr($class, -7) !== 'Factory')
        return;

    $subName = substr($class, 0, -8);
    eval("class $class extends FactoryAbstract{
        protected function getClassName(){
            return '$subName';
        }
    }");
}
WHAT IS INJECTING THESE OBJECTS?
Injector, Provider, Container
Configuration
<service id="bar" class="FooClass" shared="true"
       constructor="getInstance">
  <file>%path%/foo.php</file>
  <argument>foo</argument>
  <argument type="service" id="foo" />
  <argument type="collection">
    <argument>true</argument>
    <argument>false</argument>
  </argument>
  <configurator function="configure" />
  <call method="setBar" />
  <call method="setBar">
    <argument>foo</argument>
    <argument type="service" id="foo" />
    <argument type="collection">
      <argument>true</argument>
      <argument>false</argument>
    </argument>
  </call>
</service>
Interfaces
if($obj instanceof InjectDb){
    $obj->setDb($this->serviceLocator->getDb());
}

if($obj instanceof InjectTool){
    $obj->setTool($this->serviceLocator->getTool());
}

if($obj instanceof InjectClientBuilder){
    $obj->setClientBuilder($this->getClientBuilder());
}

if($obj instanceof InjectEvent){
    $obj->setEvent($this->serviceLocator->getEvent());
}
Duck Typing
abstract class Zend_View_Abstract
       implements Zend_View_Interface
//...
public function registerHelper($helper, $name){
//...
    if (!$helper instanceof Zend_View_Interface){
        if (!method_exists($helper, $name)){
            require_once 'Zend/View/Exception.php';
            $e = new Zend_View_Exception(
                'View helper must …');
            $e->setView($this);
            throw $e;
        }
    }
    if (method_exists($helper, 'setView')){
        $helper->setView($this);
    }
//...
Auto Wiring
$rParmList = $methodReflection->getParameters();

foreach($rParmList as $rParm ){
    $parmClass = $rParm->getClass();

    if($parmClass !== null){
        $bindConfig->getInjectionConfig()
            ->addMethodInstanceKey(
                $methodName, $parmClass->getName());
    }else{
        throw new Exception(
            "Not possible to configure automatically"
        );
    }
}
Annotations
/**
 * @Singleton
 */
class LoggerSimple{
    /**
     * @Inject Zend_Db_Adapter_Abstract
     */
    public $db;

    /**
     * @Inject
     * @Arg Zend_Db_Adapter_Abstract
     */
    public function __construct($db){
        $this->db = $db;
    }
    /**
     * @Inject
     * @Arg Zend_Db_Adapter_Abstract
     */
    public function setDb($db){
        $this->db = $db;
    }
}
/**
 * @ImplementedBy LoggerSimple
 */
interface Logger{
    public function log($message, $level);
}
$rClass = new ReflectionAnnotatedClass($config->getClass());

if($rClass->isInterface()){
   if($rClass->hasAnnotation('ImplementedBy') === false){
       throw new Exception(…);
   }

    $impClass = $rClass->getAnnotation('ImplementedBy')->value;

    if($impClass === null){
        throw new Exception (…);
    }
    $config->setImplementationClass($impClass);
}
Combine.   Win!
Adding Dependency Injection to Legacy Applications
Singleton
class Db{
    protected function __construct(){}
    protected function __clone(){}

    public static function instance(){
        static $instance = null;
        if($instance === null){
            $instance = new static();
        }
        return $instance;
    }
}
Singleton + Registry
class Registry{
    protected static $reg = array();

    public static function add($key, $value){
        static::$reg[$key] = $value;
    }

    public static function get($key){
        return static::$reg[$key];
    }
}
class Registry{
    protected static $reg = array();

    public static function add($key, $value){
        static::$reg[$key] = $value;
    }

    public static function get($key){
        $value = static::$reg[$key];
        if(is_callable($value)){
            return $value();
        }
        return $value;
    }
}
Registry::add('db', function (){return new Db();});
var_dump(Registry::get('db'));
Service Locator
class ServiceLocator{
    protected function __construct(){}
    protected function __clone(){}
    public static function instance(){
        static $instance = null;
        if($instance === null){
            $instance = new static();
        }
        return $instance;
    }

    public function getDb(){
        static $db = null;
        if($db === null){
            $db = new Db();
        }
        return $db;
    }
}
Coarse-Grained




                 Fine-Grained
Adding Dependency Injection to Legacy Applications
Design by




            Contract
class Logger{}
abstract class LoggerAbstract{}

class LoggerEcho extends LoggerAbstract{}

class LoggerFile extends LoggerAbstract{}
interface LoggerInterface{}

abstract class LoggerAbstract implements LoggerInterface{}

class LoggerEcho extends LoggerAbstract{}

class LoggerFile extends LoggerAbstract{}

class LoggerOddBall implements LoggerInterface{}
class Logger{}
abstract class Logger{}

class LoggerEcho extends Logger{}

class LoggerFile extends Logger{}
interface Logger{}

abstract class LoggerAbstract implements Logger{}

class LoggerEcho extends Logger{}

class LoggerFile extends Logger{}

class LoggerOddBall implements Logger{}
Prefer Composition Over Inheritance
WHAT’S ALREADY OUT THERE?
Adding Dependency Injection to Legacy Applications
Adding Dependency Injection to Legacy Applications
Adding Dependency Injection to Legacy Applications
YOU NEED
    A
GAME PLAN!
Adding Dependency Injection to Legacy Applications
http://joind.in/3740

T HANK Y OU!

More Related Content

What's hot

PHPUnit elevato alla Symfony2
PHPUnit elevato alla Symfony2PHPUnit elevato alla Symfony2
PHPUnit elevato alla Symfony2
eugenio pombi
 
Symfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteSymfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il cliente
Leonardo Proietti
 
Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5
Leonardo Proietti
 
Min-Maxing Software Costs
Min-Maxing Software CostsMin-Maxing Software Costs
Min-Maxing Software Costs
Konstantin Kudryashov
 
Crafting beautiful software
Crafting beautiful softwareCrafting beautiful software
Crafting beautiful software
Jorn Oomen
 
The IoC Hydra
The IoC HydraThe IoC Hydra
The IoC Hydra
Kacper Gunia
 
The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016
Kacper Gunia
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DIC
Konstantin Kudryashov
 
Introduction to Zend Framework web services
Introduction to Zend Framework web servicesIntroduction to Zend Framework web services
Introduction to Zend Framework web services
Michelangelo van Dam
 
Symfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologySymfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technology
Daniel Knell
 
PHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolvePHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolve
XSolve
 
Why is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenariosWhy is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenarios
Divante
 
Your code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnConYour code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnCon
Rafael Dohms
 
Min-Maxing Software Costs - Laracon EU 2015
Min-Maxing Software Costs - Laracon EU 2015Min-Maxing Software Costs - Laracon EU 2015
Min-Maxing Software Costs - Laracon EU 2015
Konstantin Kudryashov
 
Decoupling the Ulabox.com monolith. From CRUD to DDD
Decoupling the Ulabox.com monolith. From CRUD to DDDDecoupling the Ulabox.com monolith. From CRUD to DDD
Decoupling the Ulabox.com monolith. From CRUD to DDD
Aleix Vergés
 
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf Conference
 
PhpUnit - The most unknown Parts
PhpUnit - The most unknown PartsPhpUnit - The most unknown Parts
PhpUnit - The most unknown Parts
Bastian Feder
 
Object Calisthenics Adapted for PHP
Object Calisthenics Adapted for PHPObject Calisthenics Adapted for PHP
Object Calisthenics Adapted for PHP
Chad Gray
 
When cqrs meets event sourcing
When cqrs meets event sourcingWhen cqrs meets event sourcing
When cqrs meets event sourcing
Manel Sellés
 
Php Enums
Php EnumsPhp Enums

What's hot (20)

PHPUnit elevato alla Symfony2
PHPUnit elevato alla Symfony2PHPUnit elevato alla Symfony2
PHPUnit elevato alla Symfony2
 
Symfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteSymfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il cliente
 
Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5
 
Min-Maxing Software Costs
Min-Maxing Software CostsMin-Maxing Software Costs
Min-Maxing Software Costs
 
Crafting beautiful software
Crafting beautiful softwareCrafting beautiful software
Crafting beautiful software
 
The IoC Hydra
The IoC HydraThe IoC Hydra
The IoC Hydra
 
The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DIC
 
Introduction to Zend Framework web services
Introduction to Zend Framework web servicesIntroduction to Zend Framework web services
Introduction to Zend Framework web services
 
Symfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologySymfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technology
 
PHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolvePHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolve
 
Why is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenariosWhy is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenarios
 
Your code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnConYour code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnCon
 
Min-Maxing Software Costs - Laracon EU 2015
Min-Maxing Software Costs - Laracon EU 2015Min-Maxing Software Costs - Laracon EU 2015
Min-Maxing Software Costs - Laracon EU 2015
 
Decoupling the Ulabox.com monolith. From CRUD to DDD
Decoupling the Ulabox.com monolith. From CRUD to DDDDecoupling the Ulabox.com monolith. From CRUD to DDD
Decoupling the Ulabox.com monolith. From CRUD to DDD
 
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
 
PhpUnit - The most unknown Parts
PhpUnit - The most unknown PartsPhpUnit - The most unknown Parts
PhpUnit - The most unknown Parts
 
Object Calisthenics Adapted for PHP
Object Calisthenics Adapted for PHPObject Calisthenics Adapted for PHP
Object Calisthenics Adapted for PHP
 
When cqrs meets event sourcing
When cqrs meets event sourcingWhen cqrs meets event sourcing
When cqrs meets event sourcing
 
Php Enums
Php EnumsPhp Enums
Php Enums
 

Similar to Adding Dependency Injection to Legacy Applications

PHPUnit でよりよくテストを書くために
PHPUnit でよりよくテストを書くためにPHPUnit でよりよくテストを書くために
PHPUnit でよりよくテストを書くために
Yuya Takeyama
 
Things I Believe Now That I'm Old
Things I Believe Now That I'm OldThings I Believe Now That I'm Old
Things I Believe Now That I'm Old
Ross Tuck
 
Unittests für Dummies
Unittests für DummiesUnittests für Dummies
Unittests für Dummies
Lars Jankowfsky
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
Rifat Nabi
 
Tidy Up Your Code
Tidy Up Your CodeTidy Up Your Code
Tidy Up Your Code
Abbas Ali
 
Code moi une RH! (PHP tour 2017)
Code moi une RH! (PHP tour 2017)Code moi une RH! (PHP tour 2017)
Code moi une RH! (PHP tour 2017)
Arnaud Langlade
 
How Kris Writes Symfony Apps
How Kris Writes Symfony AppsHow Kris Writes Symfony Apps
How Kris Writes Symfony Apps
Kris Wallsmith
 
Melhorando sua API com DSLs
Melhorando sua API com DSLsMelhorando sua API com DSLs
Melhorando sua API com DSLs
Augusto Pascutti
 
PHP Experience 2016 - [Palestra] Melhorando a comunicação da API através de DSL
PHP Experience 2016 - [Palestra] Melhorando a comunicação da API através de DSLPHP Experience 2016 - [Palestra] Melhorando a comunicação da API através de DSL
PHP Experience 2016 - [Palestra] Melhorando a comunicação da API através de DSL
iMasters
 
50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes
Azim Kurt
 
laravel tricks in 50minutes
laravel tricks in 50minuteslaravel tricks in 50minutes
laravel tricks in 50minutes
Barang CK
 
ZF2 for the ZF1 Developer
ZF2 for the ZF1 DeveloperZF2 for the ZF1 Developer
ZF2 for the ZF1 Developer
Gary Hockin
 
BEAR DI
BEAR DIBEAR DI
Command Bus To Awesome Town
Command Bus To Awesome TownCommand Bus To Awesome Town
Command Bus To Awesome Town
Ross Tuck
 
Oops in php
Oops in phpOops in php
Meet Magento Sweden - Magento 2 Layout and Code Compilation for Performance
Meet Magento Sweden - Magento 2 Layout and Code Compilation for PerformanceMeet Magento Sweden - Magento 2 Layout and Code Compilation for Performance
Meet Magento Sweden - Magento 2 Layout and Code Compilation for Performance
Ivan Chepurnyi
 
PHP for Adults: Clean Code and Object Calisthenics
PHP for Adults: Clean Code and Object CalisthenicsPHP for Adults: Clean Code and Object Calisthenics
PHP for Adults: Clean Code and Object Calisthenics
Guilherme Blanco
 
Bacbkone js
Bacbkone jsBacbkone js
Taming Command Bus
Taming Command BusTaming Command Bus
Taming Command Bus
Krzysztof Menżyk
 
Migrating to dependency injection
Migrating to dependency injectionMigrating to dependency injection
Migrating to dependency injection
Josh Adell
 

Similar to Adding Dependency Injection to Legacy Applications (20)

PHPUnit でよりよくテストを書くために
PHPUnit でよりよくテストを書くためにPHPUnit でよりよくテストを書くために
PHPUnit でよりよくテストを書くために
 
Things I Believe Now That I'm Old
Things I Believe Now That I'm OldThings I Believe Now That I'm Old
Things I Believe Now That I'm Old
 
Unittests für Dummies
Unittests für DummiesUnittests für Dummies
Unittests für Dummies
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
 
Tidy Up Your Code
Tidy Up Your CodeTidy Up Your Code
Tidy Up Your Code
 
Code moi une RH! (PHP tour 2017)
Code moi une RH! (PHP tour 2017)Code moi une RH! (PHP tour 2017)
Code moi une RH! (PHP tour 2017)
 
How Kris Writes Symfony Apps
How Kris Writes Symfony AppsHow Kris Writes Symfony Apps
How Kris Writes Symfony Apps
 
Melhorando sua API com DSLs
Melhorando sua API com DSLsMelhorando sua API com DSLs
Melhorando sua API com DSLs
 
PHP Experience 2016 - [Palestra] Melhorando a comunicação da API através de DSL
PHP Experience 2016 - [Palestra] Melhorando a comunicação da API através de DSLPHP Experience 2016 - [Palestra] Melhorando a comunicação da API através de DSL
PHP Experience 2016 - [Palestra] Melhorando a comunicação da API através de DSL
 
50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes
 
laravel tricks in 50minutes
laravel tricks in 50minuteslaravel tricks in 50minutes
laravel tricks in 50minutes
 
ZF2 for the ZF1 Developer
ZF2 for the ZF1 DeveloperZF2 for the ZF1 Developer
ZF2 for the ZF1 Developer
 
BEAR DI
BEAR DIBEAR DI
BEAR DI
 
Command Bus To Awesome Town
Command Bus To Awesome TownCommand Bus To Awesome Town
Command Bus To Awesome Town
 
Oops in php
Oops in phpOops in php
Oops in php
 
Meet Magento Sweden - Magento 2 Layout and Code Compilation for Performance
Meet Magento Sweden - Magento 2 Layout and Code Compilation for PerformanceMeet Magento Sweden - Magento 2 Layout and Code Compilation for Performance
Meet Magento Sweden - Magento 2 Layout and Code Compilation for Performance
 
PHP for Adults: Clean Code and Object Calisthenics
PHP for Adults: Clean Code and Object CalisthenicsPHP for Adults: Clean Code and Object Calisthenics
PHP for Adults: Clean Code and Object Calisthenics
 
Bacbkone js
Bacbkone jsBacbkone js
Bacbkone js
 
Taming Command Bus
Taming Command BusTaming Command Bus
Taming Command Bus
 
Migrating to dependency injection
Migrating to dependency injectionMigrating to dependency injection
Migrating to dependency injection
 

Recently uploaded

Opencast Summit 2024 — Opencast @ University of Münster
Opencast Summit 2024 — Opencast @ University of MünsterOpencast Summit 2024 — Opencast @ University of Münster
Opencast Summit 2024 — Opencast @ University of Münster
Matthias Neugebauer
 
CHAPTER-8 COMPONENTS OF COMPUTER SYSTEM CLASS 9 CBSE
CHAPTER-8 COMPONENTS OF COMPUTER SYSTEM CLASS 9 CBSECHAPTER-8 COMPONENTS OF COMPUTER SYSTEM CLASS 9 CBSE
CHAPTER-8 COMPONENTS OF COMPUTER SYSTEM CLASS 9 CBSE
kumarjarun2010
 
RPA In Healthcare Benefits, Use Case, Trend And Challenges 2024.pptx
RPA In Healthcare Benefits, Use Case, Trend And Challenges 2024.pptxRPA In Healthcare Benefits, Use Case, Trend And Challenges 2024.pptx
RPA In Healthcare Benefits, Use Case, Trend And Challenges 2024.pptx
SynapseIndia
 
How to Build a Profitable IoT Product.pptx
How to Build a Profitable IoT Product.pptxHow to Build a Profitable IoT Product.pptx
How to Build a Profitable IoT Product.pptx
Adam Dunkels
 
Dublin_mulesoft_meetup_Mulesoft_Salesforce_Integration (1).pptx
Dublin_mulesoft_meetup_Mulesoft_Salesforce_Integration (1).pptxDublin_mulesoft_meetup_Mulesoft_Salesforce_Integration (1).pptx
Dublin_mulesoft_meetup_Mulesoft_Salesforce_Integration (1).pptx
Kunal Gupta
 
Google I/O Extended Harare Merged Slides
Google I/O Extended Harare Merged SlidesGoogle I/O Extended Harare Merged Slides
Google I/O Extended Harare Merged Slides
Google Developer Group - Harare
 
Choose our Linux Web Hosting for a seamless and successful online presence
Choose our Linux Web Hosting for a seamless and successful online presenceChoose our Linux Web Hosting for a seamless and successful online presence
Choose our Linux Web Hosting for a seamless and successful online presence
rajancomputerfbd
 
Acumatica vs. Sage Intacct vs. NetSuite _ NOW CFO.pdf
Acumatica vs. Sage Intacct vs. NetSuite _ NOW CFO.pdfAcumatica vs. Sage Intacct vs. NetSuite _ NOW CFO.pdf
Acumatica vs. Sage Intacct vs. NetSuite _ NOW CFO.pdf
BrainSell Technologies
 
Use Cases & Benefits of RPA in Manufacturing in 2024.pptx
Use Cases & Benefits of RPA in Manufacturing in 2024.pptxUse Cases & Benefits of RPA in Manufacturing in 2024.pptx
Use Cases & Benefits of RPA in Manufacturing in 2024.pptx
SynapseIndia
 
Best Practices for Effectively Running dbt in Airflow.pdf
Best Practices for Effectively Running dbt in Airflow.pdfBest Practices for Effectively Running dbt in Airflow.pdf
Best Practices for Effectively Running dbt in Airflow.pdf
Tatiana Al-Chueyr
 
BT & Neo4j: Knowledge Graphs for Critical Enterprise Systems.pptx.pdf
BT & Neo4j: Knowledge Graphs for Critical Enterprise Systems.pptx.pdfBT & Neo4j: Knowledge Graphs for Critical Enterprise Systems.pptx.pdf
BT & Neo4j: Knowledge Graphs for Critical Enterprise Systems.pptx.pdf
Neo4j
 
Girls call Kolkata 👀 XXXXXXXXXXX 👀 Rs.9.5 K Cash Payment With Room Delivery
Girls call Kolkata 👀 XXXXXXXXXXX 👀 Rs.9.5 K Cash Payment With Room Delivery Girls call Kolkata 👀 XXXXXXXXXXX 👀 Rs.9.5 K Cash Payment With Room Delivery
Girls call Kolkata 👀 XXXXXXXXXXX 👀 Rs.9.5 K Cash Payment With Room Delivery
sunilverma7884
 
WhatsApp Image 2024-03-27 at 08.19.52_bfd93109.pdf
WhatsApp Image 2024-03-27 at 08.19.52_bfd93109.pdfWhatsApp Image 2024-03-27 at 08.19.52_bfd93109.pdf
WhatsApp Image 2024-03-27 at 08.19.52_bfd93109.pdf
ArgaBisma
 
Girls Call Churchgate 9910780858 Provide Best And Top Girl Service And No1 in...
Girls Call Churchgate 9910780858 Provide Best And Top Girl Service And No1 in...Girls Call Churchgate 9910780858 Provide Best And Top Girl Service And No1 in...
Girls Call Churchgate 9910780858 Provide Best And Top Girl Service And No1 in...
maigasapphire
 
How Social Media Hackers Help You to See Your Wife's Message.pdf
How Social Media Hackers Help You to See Your Wife's Message.pdfHow Social Media Hackers Help You to See Your Wife's Message.pdf
How Social Media Hackers Help You to See Your Wife's Message.pdf
HackersList
 
Salesforce AI & Einstein Copilot Workshop
Salesforce AI & Einstein Copilot WorkshopSalesforce AI & Einstein Copilot Workshop
Salesforce AI & Einstein Copilot Workshop
CEPTES Software Inc
 
WhatsApp Spy Online Trackers and Monitoring Apps
WhatsApp Spy Online Trackers and Monitoring AppsWhatsApp Spy Online Trackers and Monitoring Apps
WhatsApp Spy Online Trackers and Monitoring Apps
HackersList
 
WPRiders Company Presentation Slide Deck
WPRiders Company Presentation Slide DeckWPRiders Company Presentation Slide Deck
WPRiders Company Presentation Slide Deck
Lidia A.
 
[Talk] Moving Beyond Spaghetti Infrastructure [AOTB] 2024-07-04.pdf
[Talk] Moving Beyond Spaghetti Infrastructure [AOTB] 2024-07-04.pdf[Talk] Moving Beyond Spaghetti Infrastructure [AOTB] 2024-07-04.pdf
[Talk] Moving Beyond Spaghetti Infrastructure [AOTB] 2024-07-04.pdf
Kief Morris
 
High Profile Girls call Service Pune 000XX00000 Provide Best And Top Girl Ser...
High Profile Girls call Service Pune 000XX00000 Provide Best And Top Girl Ser...High Profile Girls call Service Pune 000XX00000 Provide Best And Top Girl Ser...
High Profile Girls call Service Pune 000XX00000 Provide Best And Top Girl Ser...
bhumivarma35300
 

Recently uploaded (20)

Opencast Summit 2024 — Opencast @ University of Münster
Opencast Summit 2024 — Opencast @ University of MünsterOpencast Summit 2024 — Opencast @ University of Münster
Opencast Summit 2024 — Opencast @ University of Münster
 
CHAPTER-8 COMPONENTS OF COMPUTER SYSTEM CLASS 9 CBSE
CHAPTER-8 COMPONENTS OF COMPUTER SYSTEM CLASS 9 CBSECHAPTER-8 COMPONENTS OF COMPUTER SYSTEM CLASS 9 CBSE
CHAPTER-8 COMPONENTS OF COMPUTER SYSTEM CLASS 9 CBSE
 
RPA In Healthcare Benefits, Use Case, Trend And Challenges 2024.pptx
RPA In Healthcare Benefits, Use Case, Trend And Challenges 2024.pptxRPA In Healthcare Benefits, Use Case, Trend And Challenges 2024.pptx
RPA In Healthcare Benefits, Use Case, Trend And Challenges 2024.pptx
 
How to Build a Profitable IoT Product.pptx
How to Build a Profitable IoT Product.pptxHow to Build a Profitable IoT Product.pptx
How to Build a Profitable IoT Product.pptx
 
Dublin_mulesoft_meetup_Mulesoft_Salesforce_Integration (1).pptx
Dublin_mulesoft_meetup_Mulesoft_Salesforce_Integration (1).pptxDublin_mulesoft_meetup_Mulesoft_Salesforce_Integration (1).pptx
Dublin_mulesoft_meetup_Mulesoft_Salesforce_Integration (1).pptx
 
Google I/O Extended Harare Merged Slides
Google I/O Extended Harare Merged SlidesGoogle I/O Extended Harare Merged Slides
Google I/O Extended Harare Merged Slides
 
Choose our Linux Web Hosting for a seamless and successful online presence
Choose our Linux Web Hosting for a seamless and successful online presenceChoose our Linux Web Hosting for a seamless and successful online presence
Choose our Linux Web Hosting for a seamless and successful online presence
 
Acumatica vs. Sage Intacct vs. NetSuite _ NOW CFO.pdf
Acumatica vs. Sage Intacct vs. NetSuite _ NOW CFO.pdfAcumatica vs. Sage Intacct vs. NetSuite _ NOW CFO.pdf
Acumatica vs. Sage Intacct vs. NetSuite _ NOW CFO.pdf
 
Use Cases & Benefits of RPA in Manufacturing in 2024.pptx
Use Cases & Benefits of RPA in Manufacturing in 2024.pptxUse Cases & Benefits of RPA in Manufacturing in 2024.pptx
Use Cases & Benefits of RPA in Manufacturing in 2024.pptx
 
Best Practices for Effectively Running dbt in Airflow.pdf
Best Practices for Effectively Running dbt in Airflow.pdfBest Practices for Effectively Running dbt in Airflow.pdf
Best Practices for Effectively Running dbt in Airflow.pdf
 
BT & Neo4j: Knowledge Graphs for Critical Enterprise Systems.pptx.pdf
BT & Neo4j: Knowledge Graphs for Critical Enterprise Systems.pptx.pdfBT & Neo4j: Knowledge Graphs for Critical Enterprise Systems.pptx.pdf
BT & Neo4j: Knowledge Graphs for Critical Enterprise Systems.pptx.pdf
 
Girls call Kolkata 👀 XXXXXXXXXXX 👀 Rs.9.5 K Cash Payment With Room Delivery
Girls call Kolkata 👀 XXXXXXXXXXX 👀 Rs.9.5 K Cash Payment With Room Delivery Girls call Kolkata 👀 XXXXXXXXXXX 👀 Rs.9.5 K Cash Payment With Room Delivery
Girls call Kolkata 👀 XXXXXXXXXXX 👀 Rs.9.5 K Cash Payment With Room Delivery
 
WhatsApp Image 2024-03-27 at 08.19.52_bfd93109.pdf
WhatsApp Image 2024-03-27 at 08.19.52_bfd93109.pdfWhatsApp Image 2024-03-27 at 08.19.52_bfd93109.pdf
WhatsApp Image 2024-03-27 at 08.19.52_bfd93109.pdf
 
Girls Call Churchgate 9910780858 Provide Best And Top Girl Service And No1 in...
Girls Call Churchgate 9910780858 Provide Best And Top Girl Service And No1 in...Girls Call Churchgate 9910780858 Provide Best And Top Girl Service And No1 in...
Girls Call Churchgate 9910780858 Provide Best And Top Girl Service And No1 in...
 
How Social Media Hackers Help You to See Your Wife's Message.pdf
How Social Media Hackers Help You to See Your Wife's Message.pdfHow Social Media Hackers Help You to See Your Wife's Message.pdf
How Social Media Hackers Help You to See Your Wife's Message.pdf
 
Salesforce AI & Einstein Copilot Workshop
Salesforce AI & Einstein Copilot WorkshopSalesforce AI & Einstein Copilot Workshop
Salesforce AI & Einstein Copilot Workshop
 
WhatsApp Spy Online Trackers and Monitoring Apps
WhatsApp Spy Online Trackers and Monitoring AppsWhatsApp Spy Online Trackers and Monitoring Apps
WhatsApp Spy Online Trackers and Monitoring Apps
 
WPRiders Company Presentation Slide Deck
WPRiders Company Presentation Slide DeckWPRiders Company Presentation Slide Deck
WPRiders Company Presentation Slide Deck
 
[Talk] Moving Beyond Spaghetti Infrastructure [AOTB] 2024-07-04.pdf
[Talk] Moving Beyond Spaghetti Infrastructure [AOTB] 2024-07-04.pdf[Talk] Moving Beyond Spaghetti Infrastructure [AOTB] 2024-07-04.pdf
[Talk] Moving Beyond Spaghetti Infrastructure [AOTB] 2024-07-04.pdf
 
High Profile Girls call Service Pune 000XX00000 Provide Best And Top Girl Ser...
High Profile Girls call Service Pune 000XX00000 Provide Best And Top Girl Ser...High Profile Girls call Service Pune 000XX00000 Provide Best And Top Girl Ser...
High Profile Girls call Service Pune 000XX00000 Provide Best And Top Girl Ser...
 

Adding Dependency Injection to Legacy Applications

  • 9. interface Calc { public function __invoke($left, $right); } class AddCalc implements Calc { public function __invoke($left, $right) { return $left + $right; } } class SubCalc implements Calc { public function __invoke($left, $right) { return $left - $right; } }
  • 10. class Calculator{ public function __invoke(Calc $calc, $left, $right){ return $calc($left, $right); } } $calculator = new Calculator(); echo $calculator(new AddCalc(), 2, 1), "n"; echo $calculator(new SubCalc(), 2, 1), "n";
  • 15. I T N E J C H E N C I T Q I U O E N S
  • 17. class Status { public function get($system) { $client = new Zend_Http_Client(); $r = $client->setUri(SERVICE_URI) ->setParameterGet(compact('system')) ->request('GET'); if ($r->isSuccessful()) { return $r->getBody(); } return false; } }
  • 18. Constructor Injection Vs. Setter/Property Injection
  • 19. class StatusSetterInject{ protected $client; public function setClient(Zend_Http_Client $client){ $this->client = $client; } public function get($system){ $r = $this->client->setUri(SERVICE_URI) ->setParameterGet(compact('system')) ->request('GET'); if ($r->isSuccessful()){ return $r->getBody(); } return false; } }
  • 20. class StatusConstructInject{ protected $client; public function __construct(Zend_Http_Client $client){ $this->client = $client; } public function get($system){ $r = $this->client->setUri(SERVICE_URI) ->setParameterGet(compact('system')) ->request('GET'); if($r->isSuccessful()){ return $r->getBody(); } return false; } }
  • 22. class StatusInit{ protected $client; public function __construct(Zend_Http_Client $client){ $this->client = $client; $this->init(); } public function init(){ //Left empty } public function get($system){ $r = $this->client->setUri(SERVICE_URI) ->setParameterGet(compact('system')) ->request('GET'); //... } }
  • 24. class StatusConstructInjectOptional{ protected $client; public function __construct( Zend_Http_Client $client = null){ if($client === null){ $client = new Zend_Http_Client(); } $this->client = $client; } public function get($system){ $r = $this->client->setUri(SERVICE_URI) ->setParameterGet(compact('system')) ->request('GET'); //... } }
  • 25. class StatusSetterInjectOptional{ protected $client; public function setClient(Zend_Http_Client $client){ $this->client = $client; } protected function getClient(){ if ($this->client === null){ $this->client = new Zend_Http_Client(); } return $this->client; } public function get($system){ $r = $this->getClient()->setUri(SERVICE_URI) ->setParameterGet(compact('system')) ->request('GET'); //...
  • 27. class StatusClassNameOverrideConstruct{ protected $clientClass; public function __construct($class = 'Zend_Http_Client'){ $this->clientClass = $class; } public function get($system){ $client = new $this->clientClass; $r = $this->getClient()->setUri(SERVICE_URI) ->setParameterGet(compact('system')) ->request('GET'); if($r->isSuccessful()){ return $r->getBody(); } return false; } }
  • 28. class StatusClassNameOverrideSetter{ protected $clientClass = 'Zend_Http_Client'; public function setClass($class){ $this->clientClass = $class; } public function get($system){ $client = new $this->clientClass; $r = $this->getClient()->setUri(SERVICE_URI) ->setParameterGet(compact('system')) ->request('GET'); if($r->isSuccessful()){ return $r->getBody(); } return false; } }
  • 29. BUT I NEED TO CREATE OBJECTS?
  • 30. class PolyBad { public function foo($bar) { if (get_class($bar) === 'SomeOtherClass') { $tmp = new SomeClass(); } } }
  • 31. class PolyGood { public function foo(SomeClass $bar) { if ($baz instanceof SomeInterface) { // Do something } } }
  • 33. class Factory{ public function create(){ return new SimpleClass(); } }
  • 35. abstract class FactoryAbstract{ protected abstract function getClassName(); public function create(){ $class = $this->getClassName(); $argList = func_get_args(); if (count($argList) < 1){ return new $class; } $rClass = new ReflectionClass($class); return $rClass->newInstanceArgs($argList); } }
  • 36. function __autoload($class){ $classPath = str_replace('_', '/', $class); $filePath = __DIR__."/src/$classPath.php"; if (file_exists($filePath)) return require $filePath; if (substr($class, -7) !== 'Factory') return; $subName = substr($class, 0, -8); eval("class $class extends FactoryAbstract{ protected function getClassName(){ return '$subName'; } }"); }
  • 37. WHAT IS INJECTING THESE OBJECTS?
  • 40. <service id="bar" class="FooClass" shared="true" constructor="getInstance"> <file>%path%/foo.php</file> <argument>foo</argument> <argument type="service" id="foo" /> <argument type="collection"> <argument>true</argument> <argument>false</argument> </argument> <configurator function="configure" /> <call method="setBar" /> <call method="setBar"> <argument>foo</argument> <argument type="service" id="foo" /> <argument type="collection"> <argument>true</argument> <argument>false</argument> </argument> </call> </service>
  • 42. if($obj instanceof InjectDb){ $obj->setDb($this->serviceLocator->getDb()); } if($obj instanceof InjectTool){ $obj->setTool($this->serviceLocator->getTool()); } if($obj instanceof InjectClientBuilder){ $obj->setClientBuilder($this->getClientBuilder()); } if($obj instanceof InjectEvent){ $obj->setEvent($this->serviceLocator->getEvent()); }
  • 44. abstract class Zend_View_Abstract implements Zend_View_Interface //... public function registerHelper($helper, $name){ //... if (!$helper instanceof Zend_View_Interface){ if (!method_exists($helper, $name)){ require_once 'Zend/View/Exception.php'; $e = new Zend_View_Exception( 'View helper must …'); $e->setView($this); throw $e; } } if (method_exists($helper, 'setView')){ $helper->setView($this); } //...
  • 46. $rParmList = $methodReflection->getParameters(); foreach($rParmList as $rParm ){ $parmClass = $rParm->getClass(); if($parmClass !== null){ $bindConfig->getInjectionConfig() ->addMethodInstanceKey( $methodName, $parmClass->getName()); }else{ throw new Exception( "Not possible to configure automatically" ); } }
  • 48. /** * @Singleton */ class LoggerSimple{ /** * @Inject Zend_Db_Adapter_Abstract */ public $db; /** * @Inject * @Arg Zend_Db_Adapter_Abstract */ public function __construct($db){ $this->db = $db; } /** * @Inject * @Arg Zend_Db_Adapter_Abstract */ public function setDb($db){ $this->db = $db; } }
  • 49. /** * @ImplementedBy LoggerSimple */ interface Logger{ public function log($message, $level); }
  • 50. $rClass = new ReflectionAnnotatedClass($config->getClass()); if($rClass->isInterface()){ if($rClass->hasAnnotation('ImplementedBy') === false){ throw new Exception(…); } $impClass = $rClass->getAnnotation('ImplementedBy')->value; if($impClass === null){ throw new Exception (…); } $config->setImplementationClass($impClass); }
  • 51. Combine. Win!
  • 54. class Db{ protected function __construct(){} protected function __clone(){} public static function instance(){ static $instance = null; if($instance === null){ $instance = new static(); } return $instance; } }
  • 56. class Registry{ protected static $reg = array(); public static function add($key, $value){ static::$reg[$key] = $value; } public static function get($key){ return static::$reg[$key]; } }
  • 57. class Registry{ protected static $reg = array(); public static function add($key, $value){ static::$reg[$key] = $value; } public static function get($key){ $value = static::$reg[$key]; if(is_callable($value)){ return $value(); } return $value; } }
  • 58. Registry::add('db', function (){return new Db();}); var_dump(Registry::get('db'));
  • 60. class ServiceLocator{ protected function __construct(){} protected function __clone(){} public static function instance(){ static $instance = null; if($instance === null){ $instance = new static(); } return $instance; } public function getDb(){ static $db = null; if($db === null){ $db = new Db(); } return $db; } }
  • 61. Coarse-Grained Fine-Grained
  • 63. Design by Contract
  • 65. abstract class LoggerAbstract{} class LoggerEcho extends LoggerAbstract{} class LoggerFile extends LoggerAbstract{}
  • 66. interface LoggerInterface{} abstract class LoggerAbstract implements LoggerInterface{} class LoggerEcho extends LoggerAbstract{} class LoggerFile extends LoggerAbstract{} class LoggerOddBall implements LoggerInterface{}
  • 68. abstract class Logger{} class LoggerEcho extends Logger{} class LoggerFile extends Logger{}
  • 69. interface Logger{} abstract class LoggerAbstract implements Logger{} class LoggerEcho extends Logger{} class LoggerFile extends Logger{} class LoggerOddBall implements Logger{}
  • 70. Prefer Composition Over Inheritance
  • 75. YOU NEED A GAME PLAN!

Editor's Notes

  1. http://www.flickr.com/photos/jon_bradley/3360454148/sizes/o/in/photostream/http://www.flickr.com/photos/walker-chris-steph-jordan/2983082765/sizes/o/in/photostream/
  2. http://www.flickr.com/photos/santomarco/5427382270/sizes/l/in/photostream/
  3. The Hollywood principle Try to make your code ignorant of it’s context
  4. It’s a way of adding abstraction.By abstraction, we mean to abstract from view or hide.
  5. danielspils
  6. tnarik&apos;s - flickr
  7. Have you ever felt like a crash test dummyAdd automated testing
  8. Strategy PatternExplain picPic – Flickr - dominicbartolini
  9. Add pointers to dependencies
  10. Welding customHitch interfaceRope a lot of workWelder – Flickr - F0t0Synthcogdogblog – tow hitch - flickr
  11. DI should not be your goal, especially when it comes to adding DI to you’re legacy appsMaintainable codeQuality codeFlexible codeReusable codeNVJ – Flickr
  12. Bang for the Buck!Not everything needs to have DI or fit the goal you are going afterIf you’re goal is testability and you are using ZF1 for example, not every plugin or helper you create maybe worth the time it would take to create unit tests for.If you are adding DI to a code base where not everyone is on-board with the concept. This will help you fall foul of the perception you are wasting time.Being a purest in legacy code may take you to an early grave.http://misternewuzer.deviantart.com/art/Pop-Bang-Warpath-119523671
  13. What I hope to give to you are some new tools to add to your tool boxWhiteforgeflickr
  14. The Hollywood principle in practiceYou’re code should not know what it’s doing in the grand schema of things It should not be aware of it’s contexthttp://www.flickr.com/photos/duke_raoul/2262882022/sizes/l/in/photostream/
  15. Be careful, opinions vary on this topicBike shed question,It doesn’t matter when you are adding DI to legacy, because the answer is, what ever works for you right now.http://www.flickr.com/photos/sue_langford/4525633192/sizes/l/in/photostream/
  16. A helper pattern that works well with constructor injection, when you expect people to extend the classhttp://www.flickr.com/photos/22212359@N06/2307645669/sizes/l/in/photostream/
  17. http://www.flickr.com/photos/mag3737/377132773/sizes/o/in/photostream/
  18. This can get ugly with large dependency listsThat’s also a code smell that your object is trying to do too much
  19. You can combine this with constructor injection also
  20. showbiz kids - flickr
  21. Mixed string with instance
  22. If you so an string check you could combine this is injection of an object instance
  23. Hollywood principle againIf you use a class name where polymorphism can’t be used then you are calling out to the global namespace.Polymorphism is the ability to switch or replace an object of one type with an object of another typehttp://www.flickr.com/photos/demonbaby/3788532381/sizes/o/in/photostream/
  24. Many types and names (factory method, builder, containers)Dirty work happens hereNeed to inject the factory into the objects that needs to create objectsRamson – Flickr
  25. This is a little tedious for simple things
  26. CDEGlobal – Flickr
  27. Need to be careful once you start to combine with other techniques
  28. Need some class name conventionCreate the real one to overrideDon’t have to use eval
  29. So I can inject an instanceI can inject a factoryBut when and how do I do thatThis is the real hard workMichael D. Dunn – flickr
  30. Just a sophisticated factorySo we will just be building upon what we have already cover for factoriesPinkpurse - Flickr
  31. DavidMenting – Flickr
  32. Could be PHP, XML, ini, etc
  33. DAN_DAN2 – Flickr
  34. Remember this would be inside of a factoryDoesn&apos;t scale great, but not awful
  35. If it walks like a duck and it talks like a duck, then it’s a duck!http://www.flickr.com/photos/shinyhappyworld/5475939747/sizes/l/in/photostream/
  36. Code from ZF1Could go further and check type hits and param counts.Could become a mess if it’s used a lot. In PHP you will need to do some kind of introspection You can cache the result of the introspection based on class nameIn reality this is the most powerful model for decupling, but with great power come great opportunity to kill yourself
  37. Try to wire the objects up with out a central configuration and without a hand coded factory for every non-trivial object
  38. Code from a DI project I created
  39. Well sudoZalgon – Flickr
  40. Will also have to check inheritance tree for things like class level annotations
  41. Used with auto wiring
  42. If you process the annotations by creating a config object about the class, you can then cache that config object.
  43. It not always possible or advisable to be 100% DI, especially but not right away.
  44. Gives you global access and a shared instanceWill spread global access all over your codeBob.Fornal– Flickr
  45. Hard to test without adding test hooks to reset, which is evil.
  46. You can put anything you need in the registryAnyone can put or change the data in the registry
  47. A little better than just a singleton. Something still has to fill it with class instances first. Could use anonymous function.
  48. ilovememphis – Flickr
  49. Like a fixed registry with builder code baked in.Still has an issue with testing, but solutions are less evilIf you’ve ever worked with ZF1 boot-strapper and resource plugins this is much like thatIt also is a model of making the service locator pluggable
  50. cogdogblog – Flickr
  51. Refactoring&apos;sKaptain Kobold – Flickr
  52. Don&apos;t call an interface an interface
  53. Written, verbal, call a meeting, socialize it, lunch and learns. Give it time.