Problém s konstruktorem v prezenteru
- kloban
- Člen | 123
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');
}
}
- Šaman
- Člen | 2666
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
A ještě takový „detail“. Pokud má rodič konstruktor, tak by jsi jej měl volat. Stejně, jako to máš u startup metody.
- Šaman
- Člen | 2666
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
@Š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 addSetups
i addTags
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
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
@Šaman kvuli vykonu, v runtime se pak nemusi pres reflexi zjistovat zavislosti konstruktoru a vsech inject metod a properties
- Filip Procházka
- Moderator | 4668
@Šaman protože když máš presentery registrované v containeru, tak se pak vytváří cca 5× rychleji, než přes reflexi.
- Šaman
- Člen | 2666
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
@Š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.
- Šaman
- Člen | 2666
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.