Hledám správné využití DI containeru
- jstas
- Člen | 4
Zdravím!
Jako nikterak zkušený programátor jsem se nově začal zabývat Nette. Procházím si dokumentaci a tutoriály a právě jsem se dostal ke komponentám. Při testování zdánlivě jednoduchého příkladu jsem se dostal do situace, kdy si vůbec nevím rady.
Mým cílem je vytvořit několik komponent, které budou později tvořit
obsah webu, a to tak, že budou ze šablony generovány pomocí
{control nazevKomponenty}
. Vytvořil jsem třídu
BaseControl
, ve které bych rád využil pro práci s daty model
ControlManager
. Tady ale nastává můj problém. Nedaří se mi
žádnou cestou implementovat využití modelu v té komponentě.
V případě, že bych si chtěl v konstruktoru třídy
BaseControl
vytvořit instanci třídy ControlManager
(pomocí new
), Tracy zahlásí Class
‚App\Model\ControlManager‘ not found. Podezření mám na špatné
využití namespace. Nicméně… Pokud rozumím správně, všechny modely
(v mém případě zatím jen třída ControlManager
), by mohly
být v souboru config.neon zaregistrovány do DI Containeru a jako závislosti
by měly být třídám předávány v konstruktoru. Jakýkoliv můj zásah do
souboru config.neon ovšem působí chybu. Ať se snažím přidat třídu
(ControlManager
) jakkoliv, vždy mě Tracy zastaví
s Nette\DI\ServiceCreationException ve znění Class
App\Models\ControlManager used in service ‚controlManager‘
not found.
Rád bych se Vás zeptal, jestli k problému vůbec přistupuji správně, nebo jestli se obecně využívá jiná technika či přístup. Zajímá mě také adresářová struktura Nette projektu a členění do namespace.
Co by mělo být obsahem souboru config.neon? (Konkrétně zde, i obecně.) Jakým způsobem by pak měly vypadat konstruktory tříd (i třeba presenterů zcela mimo komponenty), které potřebují využít modely (závislosti)?
Nenašel by se zde prosím někdo, kdo by mi pomohl do problému trochu více zabřednout? Nástřel projektu je na adrese https://github.com/jstas/test. Pokud jsem něco špatně popsal, rád doplním.
Mnohokrát Vám předem děkuji.
S pozdravem Honza
- chemix
- Nette Core | 1310
Ahoj
Zkus postupovat podle tohodle clanku https://doc.nette.org/…kstart/model
Co jsem koukal na tvuj kod tak pokud ten clanek prectes nel bys pochopit ze DI ti pomaha s vytvarenim objektu.
Proto tve volani v konstruktoru ‘new ControlManager’ neni to co chces.
Ty chces App/Model/ControlManager zaregostrovat v config.neon v sekci services aby o nem framework vedel. Nasledne poupravis konstruktor komponenty tak ze si PREDAS V KONSTRUKTORU instanci parametrem, takze nejak
public function __construct(/App/Model/ControlManager $controlManager) {
parent::__construct();
$this->controlManager = $controlManager;
}
A uzas s DI prave prichazi, ze ty se nestaras o vytvoreni instance pomoci new, to nechas na DI a reknes mu jen ze to chces a on se onto postara, a pokud by controlManager mel v konstruktoru zavislosti na databazi a buhvincem tak se o ne DI postara a ty dostanes na podnosu prioravenou instanci tridy. Tj neresis vytvareni db contex ani dalsich 4 trid co db context ke svemu vytvoreni potrebuje
Snad jsem to pospal citelne
- David Matějka
- Moderator | 6445
ahoj, ten tvuj soubor ControlManager
nema koncovku
.php
, tak to fakt fungovat nebude :)
- jstas
- Člen | 4
Zdravím Vás!
Děkuji Vám za velmi rychlé odpovědi, jsem potěšen, že fórum takhle bleskově funguje.
Komentář od @chemix mě utvrdil v tom, že dokumentaci rozumím
správně, postupuji podle ukázek kódu taky správně (možná jsem špatně
vysvětlil, že volání new ControlManager
v konstruktoru byl jen
jeden z marných výstřelů po dlouhém hledání chyby), ale „někde“
opravdu dělám chybu, na kterou nemohu přijít.
Až potom @DavidMatějka velmi správně odhalil můj problém – za což mnohokrát děkuji! Velmi hloupá chyba, u níž si nejsem jist, jestli bych na ni někdy přišel.
Díky z Váš čas!
S pozdravem Honza