Problém s konstruktorem v prezenteru

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

V následujícím kódu je konstruktor, se kterým je problém. Laděnka hlásí Service 'application.1': Class App\AdministrationModule\Components\SignIn\SignInControlFactory needed by App\AdministrationModule\Presenters\SignPresenter::__construct() not found. Check type hint and 'use' statements.

Netušíte kde může být chyba?

Jde o to, že mám jednu aplikaci kde je hotové přihlašování uživatelů a snažím se ho přesunout do aplikace jiné.

<?php

namespace App\AdministrationModule\Presenters;

use App\AdministrationModule\Components\SignIn\SignInControl;
use App\AdministrationModule\Components\SignIn\SignInControlFactory;
use Kdyby\Doctrine\EntityManager;
use Nette,
	App\Model,
	Nette\Application\UI,
	Nette\Forms\Controls;


class SignPresenter extends UI\Presenter
{

	/**
	 * @var SignInControlFactory
	 */
	private $signInControlFactory;

	/**
	 * @var EntityManager
	 */
	private $entityManager;


	public function __construct(SignInControlFactory $signInControlFactory, EntityManager $entityManager)
	{
		$this->signInControlFactory = $signInControlFactory;
		$this->entityManager = $entityManager;
	}


	public function startup()
	{
		parent::startup();

	}


	/**
	 * @return SignInControl
	 */
	protected function createComponentSignInForm()
	{
		return $this->signInControlFactory->create();
	}


	public function actionOut()
	{
		$this->getUser()->logout();
		$this->flashMessage('You have been signed out.');
		$this->redirect('in');
	}

}
David Matějka
Moderator | 6445
+
0
-

mas to registrovany v config.neon?

kloban
Člen | 123
+
0
-

Díky, neměl. Moc ale nerozumím tomu co musím do config registrovat.

Šaman
Člen | 2666
+
+1
-

kloban napsal(a):

Díky, neměl. Moc ale nerozumím tomu co musím do config registrovat.

Stručně řečeno všechno, co má jakoukoliv souvislost s DI kontejnerem. Tedy co je zmíněno v configu, nebo co chceš aby se automaticky injectovalo do nějaké třídy. Takže všechny třídy z configu + jejich závislosti.

Ale ideálně úplně všechno. Je to lepší tahat z DIC, než vytvářet ručně. Jen presentery tam být nemusí, ale já už je tam mám taky.

David Kudera
Člen | 455
+
0
-

A ještě takový „detail“. Pokud rodič konstruktor, tak by jsi jej měl volat. Stejně, jako to máš u startup metody.

Filip Procházka
Moderator | 4668
+
0
-

@Šaman presentery se registrují automaticky od 2.3

Šaman
Člen | 2666
+
0
-

Filip Procházka napsal(a):

@Šaman presentery se registrují automaticky od 2.3

Jak to myslíš? Registrují se do DIC? Jak to, že na ně tedy nefunguje decorator, dokud je explicitně neuvedu mezi services? V níže uvedeném příkladu se do HomepagePresenteru nastaví hodnota, pokud ho odkomentuji, jinak ne. (Kompletní příklad na GitHubu, Nette 2.3.1)

services:
#	- App\Presenters\HomepagePresenter

decorator:
	App\Presenters\BasePresenter:
		setup:
			- setFoo('bar')

Editoval Šaman (5. 5. 2015 0:45)

Filip Procházka
Moderator | 4668
+
+1
-

@Šaman Ano, registrují se do DIC. Problém je v tom, že rozšíření pro DIC nemají dořešené závislosti a tím pádem se ve špatném pořadí zpracují. Nejprve se zpracuje dekorátor a až potom se registrují presentery (umí to všechno, co uměl Kdyby/PresentersLocator, takže je deprecated).

Ale addSetupsaddTags jsou public, takže by mělo jít relativně snadno dodělat to, že si ApplicationExtension vytáhe DecoratorExtension z Compiler a zavolá co je potřeba. A nebo prostě prohodit decorator až na konec :)

Nechceš to domyslet a poslat pullrequest? Udělal bych to ale zrovna mě to netrápí natolik, abych tomu dával největší prioritu.

Šaman
Člen | 2666
+
0
-

Ok, zkoušel jsem to a pokud je decorator až na konci pole, tak to funguje. Na to klidně PR pošlu.

Trochu ale přemýšlím, proč se Presentery registrují automaticky? Není to zbytečná magie, když všechny ostatní služby i komponenty si musím registrovat sám? V projektech, které jsem zatím viděl, bylo vždy méně presenterů, než třeba služeb (resp. pokud bylo více presenterů, tak jich bylo max 5).

David Matějka
Moderator | 6445
+
0
-

@Šaman kvuli vykonu, v runtime se pak nemusi pres reflexi zjistovat zavislosti konstruktoru a vsech inject metod a properties

Filip Procházka
Moderator | 4668
+
0
-

@Šaman protože když máš presentery registrované v containeru, tak se pak vytváří cca 5× rychleji, než přes reflexi.

Šaman
Člen | 2666
+
0
-

Filip Procházka napsal(a):

@Šaman protože když máš presentery registrované v containeru, tak se pak vytváří cca 5× rychleji, než přes reflexi.

Registrované ano, ale já je mám přímo vypsané v services. Dokonce na ně mám samostatný soubor jenom s presentery každého modulu.

Filip Procházka
Moderator | 4668
+
+1
-

@Šaman však v tom není žádný rozdíl. Services z configu se překládají na definice v DIC Builderu a pak se zkompilují do DIC. Akorát Nette to teď dělá automaticky. A dělá to chytře, takže když chceš něco změnit, můžeš si presenter hodit do configu a nastavit jak chceš a Nette ho tam nedá podruhé. Akorát odpadá udržování seznamu presenterů v configu.

Trochu ale přemýšlím, proč se Presentery registrují automaticky? Není to zbytečná magie, když všechny ostatní služby i komponenty si musím registrovat sám?

Presentery mají jasně definovanej kontrakt. Hledat třídy co implemetují IPresenter je celkem brnkačka, nechtěl bych ale aby mi Nette registrovalo do DIC úplně všechny třídy co najde v projektu.

Unlink
Člen | 298
+
0
-

Šaman napsal(a):

Ok, zkoušel jsem to a pokud je decorator až na konci pole, tak to funguje. Na to klidně PR pošlu.

Ahoj @Šaman, v akom stave je ten PR, akurát som zistil že by sa mi to celkom hodilo, ak treba tak ten PR spravím.
Ďakujem

Editoval Unlink (17. 5. 2015 13:36)

Šaman
Člen | 2666
+
0
-

Unlink napsal(a):

Šaman napsal(a):

Ok, zkoušel jsem to a pokud je decorator až na konci pole, tak to funguje. Na to klidně PR pošlu.

Ahoj @Šaman, v akom stave je ten PR, akurát som zistil že by sa mi to celkom hodilo, ak treba tak ten PR spravím.
Ďakujem

Zatím jsem to neposlal, protože testy. Nějak nevim, co vlastně testovat. Hotfix je jednouchý, stačí přenést odkazovaný řádek o pozici níž, nebo na konec toho pole. Ale já to nakonec vyřešil raději tím, že si presentery stále píšu do services a používám neupravené Nette.

Unlink
Člen | 298
+
0
-

No ja som to zatiaľ vyriešil tak, že som tam tu extension cez config dal ešte raz na koniec

extensions:
    decorator2: Nette\DI\Extensions\DecoratorExtension
Unlink
Člen | 298
+
0
-

Tak už to @dg spravil :)
https://github.com/…2254d1635401