Chyba: Circular reference detected for services: Xyz

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

Už si opravdu nevím rady. :-) Mám celkem jednoduchý kód, kde mám komponentu, kterou mám nakonfigurovanou v konfiguračním souboru a presenter, kde tuto komponentu injektuji.

Komponenta:

namespace MyModule;

use Nette\Application\UI as UI;

final class MyControl extends UI\Control
{

	/** @var array */
	private $parameters = array();


	public function addParameter($key, $value)
	{
		$this->parameters[$key] = $value;
	}


	public function render()
	{
		$this->template->setFile(__DIR__ . '/MyControl.latte');
		$this->template->parameters = $this->parameters;
		$this->template->render();
	}

}

Konfigurace komponenty:

services:
	myControl:
		class: MyModule\MyControl
		setup:
			- addParameter('name', 'John Doe')

Presenter:

namespace MyModule;

use Nette,
	Nette\Application\UI as UI;

abstract class BasePresenter extends UI\Presenter
{

	/** @var MyControl */
	private $myControl;


	/**
	 * @param MyControl $myControl
	 * @return void
	 */
	public function injectMyControl(MyControl $myControl)
	{
		$this->myControl = $myControl;
	}


	/**
	 * @return MyControl
	 */
	protected function createComponentParameterList()
	{
		return $this->myControl;
	}

}

Třída BasePresenter je abstraktní, protože ji pak využívám jako nadtřídu v ostatních presenterech v modulu MyModule.

V šabloně pak komponentu parameterList, která se vytvoří v BasePresenteru, použiju klasicky takto: {parameterList}.

Vždy se ale vyhodí vyjímka Nette\InvalidStateException a celé to skončí chybou: Circular reference detected for services: myControl.

Níže pak ještě (pro úplnost :-)) přikládám kód z Laděnky, kde se vyjímka vyhazuje (řádek č. 144):

134:        /**
135:         * Creates new instance of the service.
136:         * @param  string service name
137:         * @return object
138:         * @throws MissingServiceException
139:         */
140:        public function createService($name, array $args = array())
141:        {
142:            $method = Container::getMethodName($name);
143:            if (isset($this->creating[$name])) {
144:                throw new Nette\InvalidStateException(sprintf('Circular reference detected for services: %s.', implode(', ', array_keys($this->creating))));
145:
146:            } elseif (!method_exists($this, $method) || $this->getReflection()->getMethod($method)->getName() !== $method) {
147:                throw new MissingServiceException("Service '$name' not found.");
148:            }

Řeším to už několik dní a prostě si nevím rady.

PavelJurasek
Člen | 39
+
+1
-

Problém je tu. Musíš přetížit konstruktor, aby tvá komponenta nevyžadovala Presenter při vytváření.

public function __construct()
{
	parent::__construct();
}
mkoubik
Člen | 728
+
+2
-

A hlavně neregistruj komponentu jako službu! Vytvoř si na ní továrničku: https://doc.nette.org/…tion/factory.

fary
Člen | 155
+
+1
-

OMG :-) Stačí přetížit konstruktor. Taková maličkost a člověka to nenapadne. :-) Moc díky oběma za rady. :-)