Jak vytvořit objekt pomocí továrničky definované v configu?
- Oli
- Člen | 1215
Ahoj,
nikdy jsem nepoužíval továrničky pomocí configu. Mám s tím ale tak
trochu problém.
- Když jsem jel podle dokumentace (en), tak první co, že nemám používat factories, že jsou deprecated. Jasně chápu, přesouvám do služby.
- Továrničku jsem si udělal podle dokumentace ve službě a zkusil zavolat
service:
poll:
class: Component\Poll\Polls(@pollRepository)
autowired: no
public function createComponentPoll() {
return $this->context->createPoll;
}
Tohle mě nadalo, že createPoll neexistuje. Pokud název service přepíšu na createPoll, tak to funguje, ale řekl bych, že to už nevyrábí továrnička, ale volám přímo službu.
- zkouším teda radu, na kterou jsem náhodou narazil na foru. To mě zase nadalo, že neexistuje klíčové slovo implements
Mohl by mě prosím někdo ukázat nějaký jednoduchý ucelený příklad, jak použít továrničku definovanou v configu?
Ještě dodám, že používám Nette 2.1
- David Matějka
- Moderator | 6445
radeji pouzij generovane tovarnicky, https://doc.nette.org/…tion/factory
- Oli
- Člen | 1215
matej21: Díky. Použil jsem ten návod „Jak si ušetřit psaní“. Ještě by mě zajímalo, jak dostat do konstruktoru (respektive do té třídy) parametry z configu?
nanuqcz: Díky. Přes ten context se mě to ale tak nějak líbí míň, než když to můžu normálně injectnout do třídy.
Ještě takovej akademickej dotaz, jakej je rozdíl mezi
$this->context->createService('poll');
a interface, když oba
způsoby v podstatě dělají totéž (novou instanci třídy)?
- David Matějka
- Moderator | 6445
@Oli: v neonu
services:
-
class: Component\Poll\Polls(@pollRepository)
implement: Component\Poll\PollsFactory
Ještě takovej akademickej dotaz, jakej je rozdíl mezi
$this->context->createService('poll');
a interface, když oba způsoby v podstatě dělají totéž (novou instanci třídy)?
je to o tom, ze diky factory mas jasne definovanou zavislost, nejsi zavisly na contextu, kterym skryvas realne zavislosti
Editoval matej21 (6. 2. 2014 21:08)
- Vojtěch Dobeš
- Gold Partner | 1316
Předávání parametrů zatím ve článku chybí, ale udělá se to takto:
services:
-
create: Component\Poll\Polls(%foo%)
implement: IFactory
class Polls
{
public function __construct($foo, PollsRepository $pollsRepository)
{
...
- Oli
- Člen | 1215
matej21, vojtech.dobes: Díky kluci.
Nebylo by špatný napsat to buď do dokumentace nebo na planette. V dokumentaci se pořád popisuje použití s factories, které už v Nette 2.1 nejsou. Poslal bych pull request, ale obávám se, že kromě toho co jste mě tu teď poradili neznám další možnosti :-)
- Oli
- Člen | 1215
Tohle už úplně nesouvisí s továrničkou, ale jak deklaruju v configu třídu, které předám nějaký parametry z presenteru, nějaký z neonu a kterej bude obsahovat nějaký setmetody? Ty set metody bych ani tak nepotřeboval, to jen tak pro úplnost, někde jsem to totiž viděl, že to jde.
Chtěl bych config napsat tak, abych mohl použít constructor takhle:
public function __construct($lang, $defaultLang, $translator) {
$this->lang = $lang; // předávám z presenteru
$this->defaultLang = $defaultLang; // z neonu
$this->translator = $translator; // z neonu
}
Díky
- Vojtěch Dobeš
- Gold Partner | 1316
services:
-
create: Component\Poll\Polls(%lang%, %defaultLang%) # (%lang%, %defaultLang%, @translator) při nevyužití autowiringu
implement: IFactory
parameters: [lang]
setup:
- setDefaultLang(%defaultLang%)
- setTranslator() # setTranslator(@translator) při nevyužití autowiringu
interface IFactory
{
/** @return \Component\Poll\Polls */
function create($lang);
}
- Mesiah
- Člen | 240
vojtech.dobes napsal(a):
Taky nemám zkušenost s dynamickými továrnami, tak mě prosím
neukamenujte, když to špatně poberu, ale chápu správně, že pak jen
v továrničce komponenty, Poll jak už je tady zmíněno, zavolám
$this->myInjectedInterfaceControl->create('cs');
?
V případě, kdy parametr lang nevyplním, vyskočí mi exception/notice?
Je možné dát jako parametr persistentní parametr, v neon configu?
- Vojtěch Dobeš
- Gold Partner | 1316
Přesně tak, v továrničce si člověk zavolá metodu create
na továrně.
Když se parametr lang
nepředá, tak to zařve na chybějícím
argumentu.
Konfigurace o persistentních parametrech nic neví, takže ne.
- Oli
- Člen | 1215
@vojtech.dobes: Tak jsem se dostal k tomu to vyzkoušet, ale nefunguje mě to a nejsem schopnej přijít na to, kde dělám chybu. Mám dva parametry, které přijímá constructor. Jeden bych potřeboval jako id a druhý závislost na repository. Oba ale dostanou to repository. Na tohle bych v podstatě ani factory nepotřeboval, jen bych chtěl předat oba ty parametry (id a optionRepository) do konstruktoru. Mám to takhle:
poll:
class: Component\Poll\Polls(@poolOptions, dalsi zavislosti)
implement: IPollsFactory
poolOptions:
class: Component\Poll\Options(@optionRepository)
implement: Component\Poll\IOptions
parameters: [id]
setup:
- setOptionRepository()
// IOptions
interface IOptions
{
/** @return \Component\Poll\Polls */
function create($id);
}
// Options
public function __construct($id, \Repository\OptionRepository $answersRep)
{
$this->id = $id; // dostane taky instanci \Repository\OptionRepository
$this->answersRep = $answersRep;
}
// Polls
public function __construct(IOptions $options)
{
$this->options = $options;
}
public function render()
{
$this->template->options = $this->options->create($this->id);
}
- David Matějka
- Moderator | 6445
musis rict, kam to id predat:
poolOptions:
class: Component\Poll\Options(%id%, @optionRepository)
implement: Component\Poll\IOptions
parameters: [id]
setup:
- setOptionRepository() #wtf?