Сервисы
BD
Service0
Service1
Service2
Приложение
new Роутер (маршрут, аргумент)
switch (маршрут)
new Маршрут0 (аргумент)
new Маршрут1 (аргумент)
switch (аргумент)
new A
new B
new C
тут нужна BD и Service1
...
new D
тут нужен Service0 и Service2
...
...
new Маршрут2 (аргумент)
...
new SomeClass
A
B
C
тут тоже нужна BD
...
class DB {
public $connection = 'ok';
}
class Worker {
public function __construct(DB $db, $i) {// как получить тут DB от контейнера и аргументы от workerManager ?
echo "Worker $i connection is $db->connection";
}
}
class App {
public function __construct() {
//new Router...
//new workerManager...
for ($i = 1; $i <= 10; $i++) {//тут может быть foreach со списком задач
//10 воркеров с разными аргументами...
new Worker($i); //конструктор требует DB + аргументы... а значит получить DB от Route0 и так по цепочке до App где DB можно получить в конструкторе что убивает смысл di. Или нужно подключать Router как зависимость в App, workerManager как зависимость в Router и через workerManager получать все зависимости и отправлять их в new Worker ? Но опять же Router нужно тоже через new создавать что бы передать ему динамические аргументы.
}
}
}
Описываешь, какие зависимости нужны твоим классам, и вперед
/**
* Explicit definition of parameters by their name:
*
* @Inject({"db" = "DB"})
*/
public function __construct(DB $db, $i) {
}
require './vendor/autoload.php';
$builder = new \DI\ContainerBuilder();
$builder->useAnnotations(true);
$container = $builder->build();
$container->make('App\App', [
'con' => $container
]);class DB {
public $connection = 'ok';
}
class Worker {
public function __construct(DB $db, $i) {
echo "Worker $i connection is $db->connection";
}
}
class App {
public function __construct($con) {
for ($i = 1; $i <= 10; $i++) {
$con->make('App\Worker', [
'i' => $i,
]);
}
}
}
В воркер надо передавать объект, который работает с воркером.
Если у воркера есть своя зависимость, то ее контейнер ему создаст.
$con->make то $con и есть та самая "канализация" которая идет App -> Router что бы создать Worker, а если в воркере нужно что то создать у чего есть зависимость то и туда нужно передать $con.
<?php
Class DB {
public function get() {
return 'getDB';
}
}
function db() {
return new DB();
}
Class A {
public function getB() {
$b = new B();
return $b;
}
}
Class B {
private $db;
public function __construct() {
$this->db = db()->get();
}
}
$a = new A();
$b = $a->getB();
var_dump($b);
require 'vendor/autoload.php';
(function() {
$builder = new \DI\ContainerBuilder();
$builder->addDefinitions([
'db.host' => 'localhost',
'db.user' => 'root',
'db.pass' => 'password',
//инструкция о том как создавать объект DB
'DB' => DI\create()->constructor(DI\get('db.host'), DI\get('db.user'), DI\get('db.pass')),
]);
$container = $builder->build();
//просим контейнер создать объект A
$a = $container->get('A');
$b = $a->B;
var_dump($b);
})();
Class A {
public $B;
//контейнер видит что объекту A нужен объект B и создает его
public function __construct(B $b) {
$this->B = $b;
}
}
Class B {
private $db;
//контейнер видит что объекту B нужен объект DB и создает его
public function __construct(DB $db) {
$this->db = $db;
}
}
Class DB {
private $connection = 'connection';
//контейнер не знает что подставить в конструктор DB поэтому для него нужно оставить инструкцию в addDefinitions
public function __construct($host, $user, $pass) {
}
public function get() {
return $this->connection;
}
}
class Main
{
public $db; // само собой можно геттеры сеттеры делать или сами методы по работе с базой тут определить
}
class Work
{
function __construct($main)
{
$this->main=$main;
}
function do()
{
$this->main->db->connect(...)
}
}