Service container sharen
Hallo,
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?
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?
Je zou een ContainerAware klasse en ContainerAwareInterface kunnen maken en alle objecten die dat implementeren (zoals controllers en models) de container mee kunnen geven.
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.
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....
Kun je niet je controllers een "general controller" laten extenden? En dat je dan de container meegeeft aan de constructor van die general controller?
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;
});
?>




