Nette 3: dependency injection

10.10.2018
3 min read
417 words

Jak by mohlo vypadat dependency injection v Nette 3.0.

Již jednou jsem psal o dependency injection v Nette, konkrétně Nette - jak zapisovat služby (extension / neon). Do dnes asi můj nejlepší článek.

K tomuto článku mě donutily změny v nette/di repozitáři. Myslím, že David zase vymyslel elegantní features. A také tyto tweety.

geekovo nettefw

Nette 2.4

Pojďme si zopakovat některé základní definice zapisování služeb v NEONu.

Anonymní služba

services:
    - App\Model\FacebookAuthenticator
$container->getByType(App\Model\FacebookAuthenticator::class);

Pojmenovaná služba

services:
    facebookAuth: App\Model\FacebookAuthenticator
$container->getByType(App\Model\FacebookAuthenticator::class);
$container->getService('facebookAuth');

Předávání závislostí

services:
    - App\Model\FacebookAuthenticator(
        App\Model\MonologLogger(@monolog),
        App\Model\CacheAdapter(
            FileCache(%tempDir%/auth)
        )
    )
$container->getByType(App\Model\FacebookAuthenticator::class);

Volání metod na službě

services:
    facebookAuth:
        class: App\Model\FacebookAuthenticator
        setup:
            # autowiring vybere správnou službu
            - setLogger
            # sám definuji konkrétní pojmenovanou službu
            - setLogger(@monologLogger)
            # sám definuji konkrétní anonymní službu
            - setLogger(@App\Model\MonologLogger)
$container->getByType(App\Model\FacebookAuthenticator::class);
$container->getService('facebookAuth');

Více služeb stejného typu

services:
    facebookAuth:
        class: App\Model\FacebookAuthenticator
        autowired: false
    twitterAuth:
        class: App\Model\TwitterAuthenticator
        autowired: false
$container->getService('facebookAuth');
$container->getService('twitterAuth');

Tagování

services:
    middleware1:
        class: App\Model\CacheMiddleware
        tags: [middleware: 100]
    middleware2:
        class: App\Model\LoggingMiddleware
        tags: [middleware: 200]
    middleware3:
        class: App\Model\ApitteMiddleware
        tags: [middleware: 300]
$names = $container->findByTag('middleware');
foreach ($names as $name => $tag) {
    // $tag = [middleware => 100]
    $container->getService($name);
}

Injectování

namespace App\Model;

class DatabaseAuthenticator
{
    /** @var App\Model\MonologLogger @inject */
    public $logger;
}
services:
    authenticator:
        class: App\Model\DatabaseAuthenticator
        inject: true

    # alternativni zapis
    - { class: App\Model\DatabaseAuthenticator, inject: true }

Extra

services:
    # vsechny parametry z kontejneru
    - App\Model\Foo(@container::parameters)

    # vsechny sluzby daneho typu
    - App\Model\Foo(@container::findByType(App\Model\Bar))

    # volani fce getenv()
    - App\Moel\Foo(::getenv(NODE_DEBUG))

Nette 3.0+

V Nette 2.4 jdou definovat služby mnoha způsoby a při troše cviku jste schopní vyřešit opravdu cokoli.

Podle aktivity v nette/di bychom v Nette 3 mohli narazit na nové vychytávky.

Autowiring pole služeb podle typu

namespace App\Model;

class FacebookAuthenticator
{
    /** @param AuthSubscriber[] $subscribers */
    public function __construct(array $subscribers) { ... }
}
services:
    - App\Mode\CacheCleanerAuthSubscriber
    - App\Model\LoggerAuthSubscriber

    - App\Model\FacebookAuthenticator( types(App\Model\AuthSubscriber) )

Autowiring pole služeb podle tagu

services:
    - { class: App\Mode\CacheCleanerAuthSubscriber, tags: [auth]}
    - { class: App\Mode\LoggerAuthSubscriber, tags: [auth]}

    - App\Model\AuthentictorMiddleware( tags(auth) )

Expandování klíče i hodnoty

parameters:
    username: user
    password: 1234

services:
    # [%username% => 1234] v Nette 2.4
    - Nette\Security\SimpleAuthenticator({%username%: %password%})
    # [user => 1234] v Nette 3.0+
    - Nette\Security\SimpleAuthenticator({%username%: %password%})

Myslím, že se máme na co těšit. Sledujte vývoj! 👀 🎉


A jak používáte nette/di vy? Napište mi to do komentářů.

Currently working

I am currently digging deeper to serverless stuf. Also trying to do my best around Nette [contributte.org & componette.org]. Taking care of 242 libraries across various Github organizations.