1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
:PROPERTIES:
:ID: 49387584-0ee5-42ab-bc90-648062e74a91
:END:
#+title: Dependency Injection
* Dependency Injection
Часть инверсии контроля, которая занимается инициализацией объектов и их
зависимостей обычно в единственном экземпляре. Объекты обычно передают в
аргументах функций-конструкторов класса, а штука находящая объекты
называется сервис-локатором.
Суть паттерна заключается в том, чтобы не инициализировать лишний раз в
конструкторе объекты вручную и не инициализировать лишний раз экземпляры
классов в принципе (IoC).
*Сервис-контейнер* -- класс, инициализирующий различные объекты, которые в
последствии хранит в одном из своих полей.
*Сервис* -- объекты, управляемые сервис-контейнером.
*Реализации:*
+ Java
http://picocontainer.com/
+ Python
https://github.com/ets-labs/python-dependency-injector
*PHP и Symfony:*
http://fabien.potencier.org/what-is-dependency-injection.html
+ Dependency Injection без контейнеров
#+begin_src php
class User
{
function __construct($storage)
{
$this->storage = $storage;
}
// ...
}
$storage = new SessionStorage('SESSION_ID');
$user = new User($storage);
#+end_src
+ Реализация возврата объекта в единственном экземпляре
#+begin_src php
class Container
{
static protected $shared = array();
// ...
public function getMailer()
{
if (isset(self::$shared['mailer']))
{
return self::$shared['mailer'];
}
$class = $this->parameters['mailer.class'];
$mailer = new $class();
$mailer->setDefaultTransport($this->getMailTransport());
return self::$shared['mailer'] = $mailer;
}
}
#+end_src
+ Реализация сервис-контейнера
#+begin_src php
class Container
{
static protected $shared = array();
protected $parameters = array();
public function __construct(array $parameters = array())
{
$this->parameters = $parameters;
}
public function getMailTransport()
{
return new Zend_Mail_Transport_Smtp('smtp.gmail.com', array(
'auth' => 'login',
'username' => $this->parameters['mailer.username'],
'password' => $this->parameters['mailer.password'],
'ssl' => 'ssl',
'port' => 465,
));
}
public function getMailer()
{
if (isset(self::$shared['mailer']))
{
return self::$shared['mailer'];
}
$class = $this->parameters['mailer.class'];
$mailer = new $class();
$mailer->setDefaultTransport($this->getMailTransport());
return self::$shared['mailer'] = $mailer;
}
}
#+end_src
*Ресурсы*
- Книга на 500+ страниц про Dependency Injection
https://livebook.manning.com/book/dependency-injection/
** DI фреймворки и библиотеки
*** PHP
- [[https://github.com/silexphp/Pimple][Pimple]] (Минималистичный DI контейнер)
|