Parametr z továrničky do konstruktoru jiné třídy

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

Zdravím,
lze zjednodušit tento PHP kod:

class Component
{
	/** @var ClassA */
	private $classA;

	function __construct($id, IClassAFactory $classAFactory)
	{
		$this->classA = $classAFactory->create($id);
	}
}
class ClassA
{
	private $id;

	function __construct($id)
	{
		$this->id = $id;
	}
}
interface IClassAFactory
{
	/** @return ClassA */
	function create($id);
}

na nějakou magii v DIC? Chtěl bych ušetřit tu továrničku na ClassA a zbytečný vytváření instance v konstruktoru Component.

Díky.

Editoval CZechBoY (29. 6. 2016 17:05)

Felix
Nette Core | 1196
+
0
-

Snazil jsem se to precist 3× a stejne jsem nepochopil co presne mas namysli. Jak vic by jsi to chtel zjednodusovat? Predat rovnou ten argument $a do IClassFactory?

Zkus mi to prosim trochu vic nastinit. :-)

CZechBoY
Člen | 3608
+
0
-

@Felix chtel bych do Component jen predat nastavenou ClassA – ten parametr by se predal pri tvorbe Component treba.

$componentFactory->create($id);

by pak zavolalo

$classA = new ClassA($id);
$component = new Component($classA);

return $classA;
David Matějka
Moderator | 6445
+
+1
-

takhle by to mohlo jit:

services:
	-
		implement: ComponentFactory
		parameters: [id]
		arguments: [ClassA(%id%)]
CZechBoY
Člen | 3608
+
0
-

@DavidMatějka jo, to vypadá dobře, nějak jsem to dal dohromady. Jen malej problém – když mám volitelnej parametr v továrničce a v konstruktoru tý komponenty ho mám jakože povinnej tak jak to udělám přes tu poloautomaticky generovanou továrničku?

class Component
{
	function __construct(array $args, ...){}
}
interface IComponentFactory
{
	/**
	 * @param int $id
	 * @param array $args
	 * @return Component
	 */
	function create($id, array $args = []);
}

díky

CZechBoY
Člen | 3608
+
0
-

Jsem chtěl aplikovat stejný postup ještě u dalšího páru a háže mi to nesmyslnou hlášku, že nemůže najít ModelA v DIC.

Service '9999_ITableFactory': Service of type aModel needed by Table::__construct() not found. Did you register it in configuration file?

services:
	-
		implement: ITableFactory
		parameters: [userID, array args = []]
		arguments: [aModel: ModelA(%userID%), userID: %userID%, args: %args%]
class Table
{
	function __construct($userID, array $args = [], SomeAutowiredClass $someClass, ModelA $aModel)
	{}
}

interface ITableFactory
{
	/**
	 * @return Table
	 */
	function create($userID, array $args = []);
}

class ModelA
{
	function __construct($userID, abc $abc, def $def)
	{}
}

Nevěděl by někdo co s tím?

Editoval CZechBoY (23. 8. 2016 14:28)

premek_k
Člen | 172
+
0
-

Smazal's temp?

CZechBoY
Člen | 3608
+
0
-

@premek_k Několikrát, navíc jsem na debug režimu

Ještě přidávám verzi Nette\DI: 2.3.11

Editoval CZechBoY (23. 8. 2016 15:52)

premek_k
Člen | 172
+
0
-

A proč tam máš to „aModel:“? Není to ten problém?

CZechBoY
Člen | 3608
+
0
-

@premek_k říkám, že do parametru se jménem aModel chci dát instanci třídy ModelA s parametrem %userID%.

premek_k
Člen | 172
+
0
-

Jj, myslel jsem si. Ale nette asi ne, podle té hlášky:

Service of type aModel needed

oproti očekávanému

Service of type ModelA needed

EDIT: GEpic byl rychlejší
EDIT: než to smazal 😀

Editoval premek_k (23. 8. 2016 21:01)

CZechBoY
Člen | 3608
+
0
-

Hm, tak jsem to zkusil dneska znova a už to chybu nevypisovalo :-)
@premek_k Je možný, že jsem tu hlášku blbě zanonymizoval anebo že v tom byla fakt chyba. Každopádně díky za pomoc.