Chyba Multiple services of type Nette\ComponentModel\IContainer
- nat
- Člen | 12
Zdravím,
mohl by mi prosím někdo poradit v čem je zakopaný pes? Přidávám komponenty pomocí injectu do presenteru.
Mám hierarchii komponenet
abstract class BaseControl extends \Nette\Application\UI\Control
class FacebookLoginControl extends BaseControl
class ProfileAsideControl extends BaseControl
Pokud dám do configuračního souboru jen jednu komponentu, pak je vše
v pořádku. V případě, že přidám i druhou vyhodí mi nette chybu:
neon
services:
facebookLoginComponent: Components\Controls\FacebookLoginControl
profileAsideControl: Components\Controls\ProfileAsideControl
Chyba
Nette\DI\ServiceCreationException
Service 'profileAsideControl': Multiple services of type Nette\ComponentModel\IContainer found: facebookLoginComponent, profileAsideControl
Editoval nat (21. 4. 2013 18:55)
- nat
- Člen | 12
enumag napsal(a):
Zřejmě máš špatný typ v té inject* metodě.
Ne Inject metoda má správný typ
public function injectAsideComponents(
\Components\Controls\ProfileAsideControl $profilAside) {
$this->profilAside = $profilAside;
}
Majkl578 napsal(a):
Komponenta by rozhodně neměla být službou. Udělej si na ni factory a předávej si ji.
No právě, že mám na projektu nette 2.0.6 a injectování komponent jako továren podporuje až 2.1 – pokud se nepletu?
Editoval nat (21. 4. 2013 22:47)
- enumag
- Člen | 2118
Automatické generování factories je až ve 2.1, ale jinak si factory jako službu můžeš přidat už ve 2.0. Jen ji budeš muset sám napsat.
Jo a tu chybu to hází kvůli konsturktoru jednoho z rodičů.
Editoval enumag (21. 4. 2013 22:52)
- Majkl578
- Moderator | 1364
nat napsal(a):
No právě, že mám na projektu nette 2.0.6 a injectování komponent jako továren podporuje až 2.1 – pokud se nepletu?
Není nic jednoduššího než si napsat vlastní factory (zde příklad s 1 závislostí):
<?php
class SomeControlFactory extends Nette\Object
{
/** @var Foo */
private $foo;
public function __construct(Foo $foo)
{
$this->foo = $foo;
}
/**
* @return SomeControl
*/
public function create()
{
return new SomeControl($this->foo);
}
}
V configu si pak registruješ tuto factory jako službu:
services:
- SomeControlFactory
V presenteru injectneš tuto create:
/** @var SomeControlFactory */
protected $someControlFactory;
public function injectSomeControlFactory(SomeControlFactory $someControlFactory)
{
$this->someControlFactory = $someControlFactory;
}
A v továrničce si od ní necháš komponentu vytvořit:
protected function createComponentSome()
{
return $this->someControlFactory->create();
}
- Majkl578
- Moderator | 1364
hAssassin napsal(a):
mohl bys mi please explicitne rict, k cemu to skutecne dobre je? misto toho abych si tu komponentu vytvarel sam az v tovarnicce v presenteru? diky…
Představ si komponentu, která má závislost na 3 službách. Abys ji mohl v presenteru instanciovat, musel bys prvně do presenteru předat všechny ty 3 služby a následně je při instanciaci komponenty předat jí. Teď si představ následující situace:
- Chci komponentu použít na více místech (protože je to komponenta, už z principu se to přímo vybízí), např. v 5 presenterech – musel bych tohle udělat na všech místech.
- Potřebuji komponentě přidat závislost na další službu – musel bych najít všechny presentery používající ji, ve všech si předat tu novou službu a všude ji nově předávat.
- Celé se to ještě víc zamotá, když budu chtít naši komponentu použít uvnitř jiné komponenty. :)
Tím, že si na ni udělám továrničku a pak předávám pouze ji, nemusím řešit žádný z výše uvedených problémů. Ať už komponentě přidám závislost nebo ne, továrna bude pořád stejná (samozřejmě že fyzicky nebude, protože tam přibude např. závislost, ale pro účely DI (autowire) a následného vytvoření samotné komponenty se nic nemění).