A simple lightweight dependency injection container for PHP.
DiContainer.php
<?php
class DiContainer {
protected $services = array();
protected $instances = array();
public function register($serviceName, $className){
$service = new Service($className, $this);
$this->services[$serviceName] = $service;
return $service;
}
public function getInstance($serviceName){
if(!isset($this->services[$serviceName])){
throw new RuntimeException(sprintf( "Failed to get service '%s'. Service is not registered", $serviceName));
}
$service = $this->services[$serviceName];
$refClass = new ReflectionClass($service->getClassName());
return $refClass->newInstanceArgs($service->getArguments());
}
public function getSingleInstance($serviceName){
if(isset($this->instances[$serviceName])){
return $this->instances[$serviceName];
}
$instance = $this->getInstance($serviceName);
$this->instances[$serviceName] = $instance;
return $instance;
}
public function __get($serviceName){
return $this->getInstance($serviceName);
}
}
class Service{
protected $className;
protected $diContainer;
protected $serviceArgs = array();
public function __construct($className, $diContainer){
$this->className = $className;
$this->diContainer = $diContainer;
}
public function getClassName(){
return $this->className;
}
public function addArgument($argument){
if(is_string($argument)){
if (substr($argument,0,2)=='@@'){
$serviceName = substr($argument,2);
$argument = $this->diContainer->getInstance($serviceName);
}
}
$this->serviceArgs[] = $argument;
return $this;
}
public function getArguments(){
return $this->serviceArgs;
}
}
?>
Usage
<?php
include 'DiContainer.php';
class Mailer {
private $transport;
public function __construct($transport){
$this->transport = $transport;
}
}
class Smtp{
public function __construct($host, $port, $user, $pass){
// Process arguments
}
}
$DiContainer = new DiContainer();
$DiContainer->register('smtp', 'Smtp')
->addArgument('host')
->addArgument('port')
->addArgument('user')
->addArgument('pass');
$DiContainer->register('mailer', 'Mailer')
->addArgument('@@smtp');
$mailer = $DiContainer->getInstance('mailer');
print_R($mailer); exit;
?>
No comments:
Post a Comment