Novinky v Nette DI 3.0 beta1

před 7 měsíci

David Grudl
Nette Core | 6849
+
+14
-

Před chvílí vyšla první betaverze Nette DI 3.0. Prosím, otestujte ji.

Jaké jsou novinky?

Proměnné lze používat v klíčích

parameters:
    username: user
    password: 1234
    serviceName: auth

services:
    %serviceName%: Nette\Security\SimpleAuthenticator([%username%: %password%])

Autowiring kolekce služeb

Automaticky předá do konstruktoru pole všech objektů AuthSubscriber z kontejneru.

namespace App\Model;

class FacebookAuthenticator
{
    /**
     * @param AuthSubscriber[] $subscribers
     */
    public function __construct(array $subscribers) { ... }
}

Kolekce služeb v konfiguraci

Obdoba výše zmíněného autowiringu kolekce služeb, jen definovaná ručně v konfiguraci pomocí typed():

services:
    - App\Model\CacheCleanerAuthSubscriber # implementuje App\Model\AuthSubscriber
    - App\Model\LoggerAuthSubscriber      # implementuje App\Model\AuthSubscriber

    # předá pole obou subscriberů
    - App\Model\FacebookAuthenticator( typed(App\Model\AuthSubscriber) )

Nebo pomocí tagů a tagged():

services:
    -
        factory: App\Model\CacheCleanerAuthSubscriber
        tags:
            listener: foo
    -
        factory: App\Model\LoggerAuthSubscriber
        tags:
            listener: bar

    # předá pole obou objektů s tagem 'listener'
    - App\Model\FacebookAuthenticator( tagged(listener) )

Lze vytvořit kolekci i z více tagů nebo tříd, např. tagged(listener, anothertag).

Generované multi továrny a accessory:

Nette vygeneruje implementaci pro multi-accessor nebo multi-továrnu, která umí zpřístupnit nebo vytvořit víc různých objektů podle parametru $name:

interface MultiAccessor
{
    function get($name): Listener
}
services:
    - App\Model\CacheCleanerAuthSubscriber
    - App\Model\LoggerAuthSubscriber
    third: App\Model\DummyAuthSubscriber

    - MultiAccessor(
        sub1: @App\Mode\CacheCleanerAuthSubscriber
        sub2: @App\Model\LoggerAuthSubscriber
        sub3: @third
    )

Použití:

$sub1 = $multiAccessor->get('sub1'); // vrací objekt App\Mode\CacheCleanerAuthSubscriber
$sub2 = $multiAccessor->get('sub2'); // vrací objekt App\Model\LoggerAuthSubscriber

Stejně tak lze vytvořit multitovárnu:

interface MultiFactory
{
    function create($name): Listener
}

$sub1 = $multiFactory->create('sub1'); // vyrobí nový App\Mode\CacheCleanerAuthSubscriber

Neexistující služba:

$multiFactory->create('UNDEFINED'); // throws Nette\DI\MissingServiceException

// nebo lze vytvořit nullable továrnu:
interface MultiFactory
{
    function create($name): ?Listener  // nullable typ
}

$multiFactory->create('UNDEFINED'); // vrací null

Multitovárnu lze definovat také pomocí tagů:

services:
    -
        factory: App\Model\CacheCleanerAuthSubscriber
        tags:
            listener: sub1
    -
        factory: App\Model\LoggerAuthSubscriber
        tags:
            listener: sub2

    - MultiAccessor(tagged: listener)

Objekty jsou pak dostupné pod názvy, které odpovídají hodnotám tagů, tj. sub1 a sub2.

Co se ještě objeví?

Možnost nechat automaticky přidávat jako služby určité třídy v určitých adresářích. Tedy podobně, jako to už funguje několik let u presenterů


Díky za inspiraci @Felix a https://f3l1x.io/…y-injection/

před 7 měsíci

Felix
Nette Core | 913
+
+1
-

Pekne sepsano ;-) Bude se snadneji testovat.

před 7 měsíci

CZechBoY
Člen | 3351
+
+1
-

Super.

Nešlo by místo

$multiFactory->create('sub1');
$multiFactory->create('sub2');

použít jen metodu bez parametru?

$multiFactory->createSub1();
$multiFactory->createSub2();

Interface by potom vypadal takto

interface MultiFactory
{
    function createSub1(): Sub1;
    function createSub2(): Sub2;
}

před 7 měsíci

David Matějka
Moderator | 5880
+
0
-

@CZechBoY to, co popisujes, je zcela jiny use case.

to, co David implementoval, resi situaci, kdy tovarna vraci jeden typ objektu (pripadne subtyp) a je veci konfigurace (nikoliv tedy kontraktu v rozhrani), jake definice tovarny a pod jakymi nazvy budou existovat

před 7 měsíci

David Grudl
Nette Core | 6849
+
+3
-

@CZechBoY to dává smysl, doplnil jsem to, možné jsou oba přístupy.

před 7 měsíci

josef.sabl
Backer | 152
+
+3
-

Zrovna dnes jsme řešili jeden problém, kdy jsme si říkali, že by se nám hodil „Autowiring kolekce služeb“ a druhý problém z dneška nám elegantně řeší „Možnost nechat automaticky přidávat jako služby určité třídy v určitých adresářích“. Takže: 👏