Více tříd se společným předkem

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Marek Bartoš
Nette Blogger | 1171
+
0
-

Zdravím, dokázal by mi někdo poradit, jak dostat do DI containeru dvě služby, které mají společného předka? Předek je abstraktní a vždy získávám konkrétní implementaci, tak jsem doufal, že bude ok, ale hlásí mi toto:

Service ‚application.1‘: Multiple services of type Modex\Extension\Module found: baseComponentsModule.module, errorModule.module

Přičemž třídu přidávám přes extension a vždy jde o konkrétní třídu

Editoval Mabar (11. 3. 2017 15:26)

Šaman
Člen | 2635
+
0
-

Je více možností. Buď používej jejich název a nikoliv název předka.
Nebo tam měj samozřejmě jen jednu.

Anebo jedné, kterou nepouživáš běžně, vypni v configu autowired, viz dokumentace

services:
  - Modex\Extension\FooModule

  barModule:
    class: Modex\Extension\BarModule
    autowired: no

Pak se ti při použití anotace, nebo konstruktoru vždycky doplní jen FooModule (když vyžádáš Modex\Extension\Module). Tu druhou máš pojmenovanou a v configu ji můžeš do nějaké služby dosadit explicitně

services:
  - MyService(@barModule)
Marek Bartoš
Nette Blogger | 1171
+
0
-

Vypnutí autowired je pro mě asi nejhorší možné řešení, tuhle třídu má každý modul a předává se do všech presenterů a většiny komponent, takže by jsem se upsal.

A název předka se používá jen v konstruktorech abstraktních tříd, které přepisuje potomek, takže nevím, kde může být problém.

$builder->addDefinition($this->prefix('module'))
                ->setClass($class, [$theme]);

Do $class se předává ModexModules\BaseComponents\Module a ModexModules\Error\Module a v presenterech i komponentách se žádá též o konkrétní implementaci abstraktního Modex\Extension\Module

Editoval Mabar (11. 3. 2017 16:11)

Šaman
Člen | 2635
+
0
-

Do builderu nevidím na sto procent, ale obecně bych řekl, že někde nějaká služba opravdu žádá obecný Modex\Extension\Module, jinak by to tu hlášku nevyhazovalo. Jak vypadá to „které přepisuje potomek“?

Marek Bartoš
Nette Blogger | 1171
+
0
-
public function __construct(\ModexModules\Error\Module $module) {
       parent::__construct($module);
}

Abstraktní parent presenter pak vyžaduje abstrakní classu Modex\Extension\Module

Momentálně to testuju na jednom presenteru v modulu Error a jedné komponentě v BaseComponents a pro jistotu píšu i celý namespace, takže jediné, co mě napadá je, že builder si zjištuje i celý strom předků, ale v tom případě zase nedává smysl, proč tuhle chybu nevyhazuje Nette\SmartObject

Marek Bartoš
Nette Blogger | 1171
+
+2
-

…mám to. Díky za rady, způsobila to má vlastní blbost. Zapomněl jsem, že presentery se do containeru přidávají automaticky a jeden BasePresenter nebyl abstraktní.

Šaman
Člen | 2635
+
+2
-

Aha, tak to je poprvé, co vidím v praxi důležitost abstract a final. Já si je udržuji vždy takto popsané, ale myslel jsem, že je to jen pro akademickou čistotu a případně proto, aby mi někdo nepoužíval presentery jinak, než bylo zamýšleno (dědit z final třeba). A ono to má občas i praktický dopad :)

Marek Bartoš
Nette Blogger | 1171
+
0
-

Já teď dělám vrstvu modularity nad nette, která by v budoucnu měla fungovat podobně pohodlně jako wordpress, ale ne tak prasácky a s mnohem většími možnostmi. Dá se v tom hodně využít dědičnosti, takže není den, kdy bych se abstract a final nevyhnul.