Смотрите исходный код Laravel для контейнера
Основные функции контейнеров для инъекций зависимостей:
- Создание экземпляра объекта управления контейнером в процессе настройки
- Сами объекты не знают, что они управляются Контейнером, и они не знают контейнера.
Вот почему контейнер может управлять любым объектом PHP. Объекты, использующие DI для управления зависимостями, хороши, но не являются необходимыми.
i
ii
A
logger = $logger; } public function show() { $user = little grey; $this->logger->execute($user); } } $useLogger = new UseLogger(new LogToFile()); $useLogger->show();
B
logger = $logger; } public function show() { $user = little grey; $this->logger->execute($user); } } $useLogger = new UseLogger(new LogToDD()); $useLogger->show();
iii
logger = $logger; } public function show() { $user = little grey; $this->logger->execute($user); } } $useLogger = new UseLogger(new LogToFile()); $useLogger->show(); echo '
'; $useLogger = new UseLogger(new LogToDD()); $useLogger->show();
Окончательное издание
logger = $logger; } public function show() { $user = little grey; $this->logger->execute($user); } } class SimpleContainer { // Used to store all bindings key-value protected static $container = []; public static function bind($name, Callable $resolver) { static::$container[$name] = $resolver; } public static function make($name) { if(isset(static::$container[$name])){ $resolver = static::$container[$name] ; return $resolver(); } throw new Exception("Binding does not exist in container"); } } SimpleContainer::bind(Logger::class, function () { return new LogToDD(); }); $useLogger3 = new UseLogger(SimpleContainer::make(Logger::class)); $useLogger3->show();
Пример
module = $module; } public function show(array $target){ $this->module->activate($target); } } class PowerA implements SuperModuleInterface { public function activate(array $target) { echo ''. __METHOD__; print_r(func_get_args()); } } class PowerB implements SuperModuleInterface { public function activate(array $target) { echo ''. __METHOD__; print_r(func_get_args()); } } class Container { protected $binds; protected $instances; /** * @param $abstract * @param $concrete * Bind pronouns to containers for subsequent make */ public function bind($abstract, $concrete) { if ($concrete instanceof Closure) { $this->binds[$abstract] = $concrete; } else { $this->instances[$abstract] = $concrete; } } /** * @param $abstract * @param array $parameters * @return mixed * Create Objects */ public function make($abstract, $parameters = []) { if (isset($this->instances[$abstract])) { return $this->instances[$abstract]; } // Put the container object $this in the first element of the parameter array. Use for call_user_func_array array_unshift($parameters, $this); // Here, $this - > binds [$abstract] bound closure function, the execution function parameter is $parameters return call_user_func_array($this->binds[$abstract], $parameters); } } // Create a container (later called a superfactory) $container = new Container; // Production scripts for adding super modules to the superfactory $container->bind('powerA', function($container) { return new PowerA; }); // Ibid. $container->bind('powerB', function($container) { return new PowerB; }); // Add Superman's production script to the superfactory $container->bind('superman', function($container, $moduleName) { return new Superman($container->make($moduleName)); }); echo ""; // Start production $superman_1 = $container->make('superman', ['powerA']); $superman_1->show(['a' => 1]); $superman_2 = $container->make('superman', ['powerB']); $superman_2->show(['b' => 1]);