Vyšla první betaverze Nette DI 3.0 – pojďte ji otestovat!

před 5 měsíci

David Grudl
Nette Core | 6827
+
+28
-

Právě vyšla první betaverze Nette DI 3.0. Je za ní měsíc velmi intenzivní práce, obrovský refaktoring, samozřejmě se snahou maximálně zachovat zpětnou kompatibilitu. A tu bych právě potřeboval otestovat.

  • Z pohledu uživatele by tato verze měla být 99.9% kompatibilní.
  • Z pohledu vývojáře CompilerExtension jsou drobné změny používáte-li generované továrny

Vždycky dávám enormní úsilí do zachování zpětné kompatibility. Tam, kde to nelze, generuje Nette co nejsmysluplnější chybové hlášky, aby přechod byl co nepříjemnější. Knihovny jsou velmi pečlivě pokryty testy. Nicméně i přes tohle všechno se stává a bude stávat, že něco přestane fungovat. Že vznikne nekompatibilita, která nebyla záměrná, nebo ji lze řešit lépe. Proto existují testovací verze. Od vás chci slyšet o každém problému. Takže je to o komunikaci, když místo ní budete nadávat, že „jsem něco rozbil“, nelze to brát na zřetel :-)

Nette DI prošlo obrovským a potřebným refactoringem, který otevírá úplně nové možnosti, jak lze DI kontejner vylepšovat. Obsahuje i řadu novinek, jako je autowiring polí služeb, multi-accessory a multi-továrny, apod, hodně jich je ještě v plánu, nicméně teď se chci věnovat spíše změnám v této betě.

Změny z pohledu uživatele

Z DI jsem odstranil několik věcí, které považuju za historické relikty, jako je podpora INI souborů, přímý zápis PHP kódu do konfigurace pomocí otazníků a možná něco dalšího. Pokud to potřebujete zachovat, dejte vědět. Při použití zápisu class: PDO(...) vás upozorní, že byste měli použít factory: PDO(...).

Změnou je, že nyní je vyžadována u každé služby znalost jejího typu – tj. oproti dřívějšku i u těch, co mají vypnuté autowired.

Změny z pohledu tvůrce Compiler Extensions

Tou hlavní je, že zatímco dosud interně popisoval každou službu objekt ServiceDefinition, dnes existuje definic vícero, tak například ImportedDefinition pro importované neboli dynamic služby, FactoryDefinition pro generované továrničky na základě inteface, AccessorDefinition pro generované accessory a LocatorDefinition pro multi-továrny a accessory.

Ukázka kódu pro DI 2.4:

$builder->addDefinition($this->prefix('latteFactory'))
    ->setImplement(Nette\Bridges\ApplicationLatte\ILatteFactory::class);
    ->setFactory(Latte\Engine::class)
    ->addSetup('setTempDirectory', [$this->tempDir])
    ->addSetup('setAutoRefresh', [$this->debugMode]);

Jelikož $builder->addDefinition() vrací právě objekt ServiceDefinition, který nelze pro generované továrničky použít, zahlásí Nette chybu:

Nette\DI\Definitions\ServiceDefinition::setImplement() is deprecated, use $builder->addFactoryDefinition(...) or addAccessorDefinition(...)

případně

Nette\DI\Definitions\FactoryDefinition::setFactory() is deprecated, use ->getResultDefinition()->setFactory()

Řešením je mírně upravit kód extenze, tj. jednak nahradit addDefinition() za addFactoryDefinition() případně addAccessorDefinition(), a dále protože FactoryDefinition má trošku jiné API, ještě doplníme getResultDefinition() před definici vraceného objektu:

$builder->addFactoryDefinition($this->prefix('latteFactory'))
    ->setImplement(Nette\Bridges\ApplicationLatte\ILatteFactory::class)
    ->getResultDefinition()
        ->setFactory(Latte\Engine::class)
        ->addSetup('setTempDirectory', [$this->tempDir])
        ->addSetup('setAutoRefresh', [$this->debugMode]);

Jak vidíte, této změně neušla ani LatteFactory z nette/application.

Prosím o otestování

Díky!

před 2 měsíci

hrach
Člen | 1812
+
+9
-

Už se snažím upgradovat Nextras Orm a Dbal, v podstatě nepoužívam nic krom ServiceDefinition, takže prakticky žádný problém, ale co mi přijde strašně nepohodlné je to, že metoda addDefinition je takový prasopes, který vrací jiný typ v PHP, jiný typ v PhpDoc, nemluvě o tom, že ještě něco vrací dynamicky na základě druhého argumentu.

Přimlouval bych se za to, aby se to udělalo nějak výrazně čistěji. Mj. kvůli tomu dost blbne PhpStorm, který pak neví, kterou definici metod na výsledném objektu člověk volá (Jestli na Definition, nebo na ServiceDefinition) a kvůli tomu taky zahodí deprecated příznak u metody setClass, byť je u obou.

Taky bych ocenil lepší PhpDoc – popis daných classes a metod, co je přidávají, co vlastně ty třídy dělají a umějí. U factory asi zůstal i omylem stejný popis ze service definition.

PS: najít tento thread chce taky vyšší skill. Chtělo by to někam připnout, přiznat si, že zrušené české sekce je nesmysl, …

Editoval hrach (6. 1. 17:26)

před 2 měsíci

Nick
Člen | 2
+
0
-

Chtěl bych se zeptat, jak to vypadá s vydáním Nette 3.0? Co jsem pochopil, tak 3.0 existuje teď pouze jako betaverze.
Nyní pracuji na 2.3 a chystám se na upgrade.
Vyplatí se teď upgradovat na 2.4 a potom později na 3.0, nebo si počkat?
Díky.

před 2 měsíci

David Grudl
Nette Core | 6827
+
0
-

Určitě nejprve updatuj na 2.4.

před 2 měsíci

David Grudl
Nette Core | 6827
+
0
-

hrach napsal(a):

Přimlouval bych se za to, aby se to udělalo nějak výrazně čistěji. Mj. kvůli tomu dost blbne PhpStorm, který pak neví, kterou definici metod na výsledném objektu člověk volá (Jestli na Definition, nebo na ServiceDefinition) a kvůli tomu taky zahodí deprecated příznak u metody setClass, byť je u obou.

Napadá tě, jak to řešit? Dynamické napovídání podle druhého parametru addDefinition() lze asi řešit přes .phpstorm.meta.php. Možnost je přidat metodu addServiceDefinition(), která vždycky vrátí ServiceDefinition (a odstranit @return u addDefinition). Ale v podstatě to znamená tlačit autory všech extensions, aby nahradili addDefinition() za addServiceDefinition()…

U factory asi zůstal i omylem stejný popis ze service definition.

Co konkrétně myslíš?

PS: najít tento thread chce taky vyšší skill. Chtělo by to někam připnout, přiznat si, že zrušené české sekce je nesmysl, …

Nějak to pořeším.

před 2 měsíci

hrach
Člen | 1812
+
0
-

Cele to na mě působilo nepřehledně, no. Možná kdyby existovala addServiceDefinition(), nemusí se addDefinition nutně deprecatnout.

Co konkrétně myslíš?

Snažil jsem se přijít na rozdíl mezi jednotlivýma definitions, moc jsem to nechápal, o co jde. https://github.com/…finition.php#L18

před 2 měsíci

David Grudl
Nette Core | 6827
+
0
-

Nemusí, jen pak zůstane stejná jako nyní, čímž se to co jsi psal neřeší. Nebo z ní odstraním ten @return a vznikne problém s napovídáním u současného kódu.

před 2 měsíci

LukasV
Člen | 5
+
+1
-

David Grudl napsal(a):

Nemusí, jen pak zůstane stejná jako nyní, čímž se to co jsi psal neřeší. Nebo z ní odstraním ten @return a vznikne problém s napovídáním u současného kódu.

A co tam nechat tu původní addDefinition(), která by se chovala pořád stejně a jen přidat novou addServiceDefinition(). addDefinition() by byla deprecated a v nette 4 nebo nějaké jiné velké verzi by se odstranila?

A existuje nějaké doporučení, jak psát rozšíření kompatibilní jak s nette 2.4, tak s nette 3? Vyhodnocovat to třeba podle toho, jestli existuje metoda addFactoryDefinition() nebo je nějaký elegantnější způsob?

před 29 dny

Václav Pávek
Backer | 43
+
0
-

Je znám termín kdy bude DI ve verzi RC?

Editoval Václav Pávek (17. 2. 23:11)

před 29 dny

David Grudl
Nette Core | 6827
+
+6
-

Měla by vyjít zítra.