PHP - A Simple Dependency Injection Container

A simple lightweight dependency injection container for PHP.

DiContainer.php

  1. <?php   
  2.   
  3.     class DiContainer {   
  4.            
  5.         protected $services = array();   
  6.         protected $instances = array();   
  7.            
  8.         public function register($serviceName, $className){   
  9.             $service = new Service($className, $this);   
  10.             $this->services[$serviceName] = $service;   
  11.             return $service;   
  12.         }   
  13.            
  14.         public function getInstance($serviceName){   
  15.                
  16.             if(!isset($this->services[$serviceName])){   
  17.                 throw new RuntimeException(sprintf( "Failed to get service '%s'. Service is not registered", $serviceName));   
  18.             }   
  19.                
  20.             $service = $this->services[$serviceName];   
  21.   
  22.             $refClass = new ReflectionClass($service->getClassName());   
  23.             return $refClass->newInstanceArgs($service->getArguments());   
  24.         }   
  25.            
  26.         public function getSingleInstance($serviceName){   
  27.             if(isset($this->instances[$serviceName])){   
  28.                 return $this->instances[$serviceName];   
  29.             }   
  30.                
  31.             $instance = $this->getInstance($serviceName);   
  32.             $this->instances[$serviceName] = $instance;   
  33.                
  34.             return $instance;   
  35.         }   
  36.            
  37.         public function __get($serviceName){   
  38.             return $this->getInstance($serviceName);   
  39.         }   
  40.     }   
  41.        
  42.     class Service{   
  43.         protected $className;   
  44.         protected $diContainer;   
  45.         protected $serviceArgs = array();   
  46.            
  47.         public function __construct($className, $diContainer){   
  48.             $this->className = $className;   
  49.             $this->diContainer = $diContainer;   
  50.         }   
  51.            
  52.         public function getClassName(){   
  53.             return $this->className;   
  54.         }   
  55.            
  56.         public function addArgument($argument){   
  57.             if(is_string($argument)){   
  58.                 if (substr($argument,0,2)=='@@'){   
  59.                     $serviceName = substr($argument,2);   
  60.                     $argument = $this->diContainer->getInstance($serviceName);   
  61.                 }   
  62.             }   
  63.             $this->serviceArgs[] = $argument;   
  64.             return $this;   
  65.         }   
  66.            
  67.         public function getArguments(){   
  68.             return $this->serviceArgs;   
  69.         }   
  70.     }   
  71.   
  72. ?>  

Usage

  1. <?php         
  2. include 'DiContainer.php';   
  3.        
  4. class Mailer {   
  5.     private $transport;   
  6.     public function __construct($transport){   
  7.         $this->transport = $transport;   
  8.     }   
  9. }   
  10.   
  11. class Smtp{   
  12.     public function __construct($host, $port, $user, $pass){   
  13.         // Process arguments   
  14.     }   
  15. }   
  16.        
  17. $DiContainer = new DiContainer();   
  18.   
  19. $DiContainer->register('smtp', 'Smtp')   
  20.     ->addArgument('host')   
  21.     ->addArgument('port')   
  22.     ->addArgument('user')   
  23.     ->addArgument('pass');   
  24.        
  25. $DiContainer->register('mailer', 'Mailer')   
  26.     ->addArgument('@@smtp');   
  27.        
  28. $mailer = $DiContainer->getInstance('mailer');   
  29.   
  30. print_R($mailer); exit;   
  31. ?>  

No comments:

Post a Comment