Dědění továrniček na komponenty a jejich závislosti

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

Zdravím.

Jelikož se nám ruku v ruce s DI mírně rozzbytečněli
factories v configu, řeším teď, jak správně uchopit
dědění komponent a jejich závislostí.

Jde v podstatě o to, že jedn. komponenty v mé aplikaci
dědí od společné BaseControl, na jejíž úrovni už
se vyskytují určité závislosti (helpery pro view, atd.).

Problém je v tom, že v configu jsem schopen předat
tyhle závislosti továrničce, ale ta samotná pak musí
tyhle závislosti předat dál vytvářené komponentě.

Lepší bude to ukázat na příkladě – řekněme, že budeme
mít komponentu TaskList dědící od BaseControlu a
tomu odpovídající továrničky.

BaseControlFactory.php

abstract class BaseControlFactory extends Nette\Object
{
	/** @var ViewHelpers */
	protected $helpers;

	function __construct(ViewHelpers $dh)
	{
		$this->helpers = $dh;
	}
}

BaseControl.php

abstract class BaseControl extends UI\Control
{
	/** @var ViewHelpers */
	protected $helpers;

	function injectHelpers(ViewHelpers $dh)
	{
		$this->helpers = $dh;
	}
}

TaskListControlFactory.php

class TaskListControlFactory extends BaseControlFactory
{
	function create()
	{
		$c = new TaskListControl; // (extends BaseControl)
		// predani zavislosti rucne? pro kazdou komponentu dedici od BaseControl?
		return $c;
	}
}

Zatím jsem to vyřešil přímočaře pomocí eventů,
nevýhoda je v tom, že je třeba je volat ručně.
Automatizovaná metoda mě bohužel žádná nenapadla:

abstract class BaseControlFactory extends Nette\Object
{
	/** @var ViewHelpers */
	protected $helpers;

	/** @var array */
	public $onCreate = array();

	function __construct(ViewHelpers $dh)
	{
		$this->helpers = $dh;

		$me = $this;
		$this->onCreate[] = function (Components\BaseControl $control) use ($me) {
			$control->injectHelpers( $me->defaultHelpers );
		};
	}
}
class TaskListControlFactory extends BaseControlFactory
{
	function create()
	{
		$c = new TaskListControl;
		$this->onCreate( $c ); // nutno volat v každém potomkovi...
		return $c;
	}
}

Je možné toto řešit jinak – lépe?

Díky!