DI, získání služby definované v config.neon pokaždé s novou instancí

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
vladimir
Člen | 11
+
0
-

Chtěl bych se zeptat, dá se nějak jednoduše zařídit, aby getService vracelo pokaždé novou instanci a nepoužil se tak singleton?

myšlenka byla, že bych si takhle v service předpřiravil třídu mail, a poté si tuhle přepřipravenou zprávu získával přes getService(„mail“).

Toto samozřejmě funguje jako singleton:

services:
	mail:
		factory: ServiceFactory::createMail
<?php
class ServiceFactory
{
	public static function createMail(DI\Container $container)
	{
		$sett = $container->params['mail'];
		$mail = new Nette\Mail\Message;
		$mail->setMailer($container->mailer);
		$mail->setFrom($sett["addrFrom"]);
		return $mail;
	}
}
?>
<?php
public function actionDefault()
{
	$mail1 = $this->getService("mail");
	$mail2 = $this->getService("mail");

	dump(($mail1 === $mail2)); // true
}
?>

Dá se to nějak jednoduše změnit? Nebo tohle použití vůbec nepatří mezi služby?

Jako jednoduchý fígl teď používám, že si službu klonuju, ale to mi nepřijde úplně správné.

<?php
public function actionDefault()
{
	$mail1 = $this->getService("mail");
	$mail2 = clone $mail1;;

	dump(($mail1 === $mail2)); // false
}
?>

Díky,
Vl.

duke
Člen | 650
+
0
-

Doporučuji přečíst si toto: https://forum.nette.org/…cy-injection.
Je tam pasáž, která se věnuje přímo tomuto problému. Ve zkratce jde o to, že pro tento účel není dobré definovat službu, ale přímo tovární metodu createMessage.

Akorát teda nevím, zda tohoto lze docílit přímo nějakým zápisem v configu (nejspíš ne), nebo je nutné napsat si svůj Container ručně a pak předat jeho jméno konstruktoru Configuratoru, tj.
$configurator = new Nette\Configurator('MujContainer');

Editoval duke (20. 11. 2011 1:39)

Vojtěch Dobeš
Gold Partner | 1316
+
0
-

Je třeba napsat ručně metodu – jde jen o konvenci, žádná příma podpora pro to není.

vladimir
Člen | 11
+
0
-

Chtěl jsem se ujistit, jestli to nějak přes config soubor zapsat půjde.

Takže jdu zkusit udělat vlastní Container podle popisu v daném vlákně. Ten pak bootstrapu vložím do konstruktoru Configuratoru.

Díky!

mkoubik
Člen | 728
+
0
-

Podle mě by stačilo jako službu definovat nějakej factory objekt, kterej by v konstruktoru přijímal container a měl jednu metodu create(), ale použití je pak o něco delší.