Service container sharen
ik wil een simpele servie container voor een mail service en een db service. Die container wordt momenteel gedeclareerd in mijn index bestand maar ik wil hem toegankelijk maken voor al mijn models en controllers zodat ik in mijn models de db service kan ophalen en in mijn controllers een mail service bijvoorbeeld.
Is het een slim idee om dan aan de controller en de model class die word geextend de container mee te geven als constructor of is er een andere / beter oplossing?
Er is alleen 1 hele grote MAAR: Het injecteren/meegeven van een container is het container locator pattern, dit is een antipattern (wat betekend dat het een aanduiding is van slecht design). Beter is het deze controllers en models services maken alleen die dingen meegeven die die controller nodig heeft.
Dan valt heel dat DI princiepe weg? :o Nu zie ik het niet meer....
Aanvulling op Ozzie ik zou de GeneralController zoals ozzie beschrijft wel abstract maken. danwel een Interface gebruiken zoals Wouter zegt. Ik ben zelf natuurlijk geen OO Guru dus ik denk dat je van Wouter wel een leuk tegenargument krijgt maar dat moeten we maar incasseren ^^.
Quote:
Dan valt heel dat DI princiepe weg?
Wanneer en waarom? Ik denk dat je even DI verkeerd begrijpt.
En Ozzie's GeneralController is natuurlijk geweldig en je ziet dit in vele grote frameworks, maar zoals ik al zei, het is een duidelijke code smell. De container is een klasse die alleen in de outer scope mag leven en niet in de inner scope van klassen.
Wat je dus eigenlijk moet doen is van elke controller een service maken en dan alleen de services meegeven die de controller nodig hebt. Bijv:
Code (php)
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
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
<?php
class PageController
{
private $request;
private $doctrine;
private $templating;
public function __construct(Request $request, Templating $templating)
{
$this->request = $request;
$this->templating = $templating;
}
public function showAction()
{
$request = $this->request;
$id = $request->query->get('id');
$page = $this->doctrine->getRepository('...')->findOne($id);
return $this->templating->parse('...', array('page' => $page));
}
public function setDoctrine(Doctrine $doctrine)
{
$this->doctrine = $doctrine;
}
}
// service configuratie
$container->set('page_controller.class', 'PageController');
$container->set('page_controller', function ($c) {
$controller = new $c->get('page_controller.class')($c->get('request'), $c->get('templating'));
$controller->setDoctrine($c->get('doctrine'));
return $controller;
});
?>
class PageController
{
private $request;
private $doctrine;
private $templating;
public function __construct(Request $request, Templating $templating)
{
$this->request = $request;
$this->templating = $templating;
}
public function showAction()
{
$request = $this->request;
$id = $request->query->get('id');
$page = $this->doctrine->getRepository('...')->findOne($id);
return $this->templating->parse('...', array('page' => $page));
}
public function setDoctrine(Doctrine $doctrine)
{
$this->doctrine = $doctrine;
}
}
// service configuratie
$container->set('page_controller.class', 'PageController');
$container->set('page_controller', function ($c) {
$controller = new $c->get('page_controller.class')($c->get('request'), $c->get('templating'));
$controller->setDoctrine($c->get('doctrine'));
return $controller;
});
?>