Nette 3.0 – vytvoření služby s dynamickými parametry
- juklicek
- Člen | 12
Ahoj, aktuálně migrujeme rozsáhlou aplikaci na nette3. Narážíme na problém s vytvářením service s dynamickými parametry. Dříve jsme v configu DI měli takto:
services:
my:
class: App\MyService
parameters: [a]
arguments: [%a%]
Nette 3 nám hlásí:
Nette\DI\InvalidConfigurationException: Unexpected option
‚services › my › parameters‘
zatím marně pátráme co s tím.
Děkuji za pomoc
- David Grudl
- Nette Core | 8227
A co by to mělo přesně dělat? Resp. jak s takovou službou pak pracujete?
- juklicek
- Člen | 12
:) Bál jsem se této odpovědi.
No používáme to, když je potřeba již za běhu aplikace vytvořit službu
s různými parametry.
Tzn. zjednodušeně, když pak voláme
$service1 = $this->container->createService('my', 'neco1');
$service2 = $this->container->createService('my', 'neco2');
získám servis jednou s parametrem neco1 a jednou s neco2
V reálu má většinou servis v konstruktoru více závislostí – x
běžných, a třeba jen jeden ten dynamický, který je třeba měnit
za běhu.
services:
my:
class: App\MyService
parameters: [userID]
arguments: [@someService1, @someService2, %userID%]
pak šlo za běhu získat instanci s extra parametrem:
$service = $this->container->createService('my', '123');
Díky za tip!
- juklicek
- Člen | 12
@CZechBoY dík za tip – to nám třeba pomůže při samotném refactoringu, ale stále si nejsme jistí, na co to refaktorovat.
Nette umí (umělo) pomáhat s továrničkami také tímto způsobem:
https://doc.nette.org/…tion/factory
Ale řekněte mi, jak komponentě RegistrationControl (do konstruktoru), předám metodou RegistrationControlFactory->create(xy) ten parametr xy?
Tam dříve zase fungovali ty parameters, ale nette 3.0 to odmítá..:/
Kdo používá v nette komponenty tak to musí řešit pořád … nebo mi něco uniká? :)
Díky!
- janpecha
- Backer | 75
Od Nette 2.3 (či tak nějak) si to dokáže ten dynamický parametr
zpracovat samo – tj. pro
RegistrationControlFactory->create(xy)
stačí něco jako:
services:
- IRegistrationControlFactory
interface IAbcFactory
{
function create($xy);
}
class RegistrationControl
{
public function __construct($xy, SomeService1 $someService1, SomeService2 $someService2)
{}
}
Takže v configu není nutné to parameters
uvádět.
- David Grudl
- Nette Core | 8227
juklicek napsal(a):
Tzn. zjednodušeně, když pak voláme
$service1 = $this->container->createService('my', 'neco1'); $service2 = $this->container->createService('my', 'neco2');
Rozumím.
Tomuhle použití kontejneru se říká Service Locator a Nette se mu snaží od verze 2.0 vyhýbat a nahrazovat za DI. Hlavní rozdíl je v tom, že místo volání metody nad neurčitým containerem, kde není zcela jasné, co umí a vrací za objekt, se volají metody nad jasně definovanou třídou, kde je tedy evidentní, co přesně vrací. Takovou třídu umí DI vygenerovat, stačí vytvořit pouze její interface. Třeba jak psal @janpecha.
U všech těch 500 služeb je potřeba předávat vlastní parametry, tj.
druhý a další parameter u createService()
?