Kontener Nette DI
Nette DI jest jedną z najciekawszych bibliotek Nette. Potrafi generować i automatycznie aktualizować skompilowane kontenery DI, które są ekstremalnie szybkie i niezwykle łatwe w konfiguracji.
Postać usług, które ma tworzyć kontener DI, definiujemy zazwyczaj za pomocą plików konfiguracyjnych w formacie NEON. Kontener, który ręcznie utworzyliśmy w poprzednim rozdziale, zapisałby się tak:
parameters:
db:
dsn: 'mysql:'
user: root
password: '***'
services:
- Nette\Database\Connection(%db.dsn%, %db.user%, %db.password%)
- ArticleFactory
- UserController
Zapis jest naprawdę zwięzły.
Wszystkie zależności zadeklarowane w konstruktorach klas ArticleFactory
i UserController
Nette DI
samo wykryje i przekaże dzięki tzw. autowiringu, dlatego
w pliku konfiguracyjnym nie trzeba niczego podawać. Więc nawet jeśli dojdzie do zmiany parametrów, nie musisz niczego
zmieniać w konfiguracji. Kontener Nette automatycznie się przgeneruje. Ty możesz skupić się wyłącznie na rozwoju
aplikacji.
Jeśli chcemy przekazywać zależności za pomocą setterów, użyjemy do tego sekcji setup.
Nette DI generuje bezpośrednio kod PHP kontenera. Wynikiem jest więc plik .php
, który możesz otworzyć
i studiować. Dzięki temu dokładnie widzisz, jak działa kontener. Możesz go również debugować w IDE i krokowo śledzić.
A co najważniejsze: wygenerowany PHP jest ekstremalnie szybki.
Nette DI potrafi również generować kod fabryk na
podstawie dostarczonego interfejsu. Dlatego zamiast klasy ArticleFactory
wystarczy nam stworzyć w aplikacji tylko
interfejs:
interface ArticleFactory
{
function create(): Article;
}
Cały przykład znajdziesz na GitHubie.
Samodzielne użycie
Wdrożenie biblioteki Nette DI do aplikacji jest bardzo łatwe. Najpierw zainstalujemy ją Composerem (ponieważ pobieranie zipów jest taaak przestarzałe):
composer require nette/di
Poniższy kod tworzy instancję kontenera DI zgodnie z konfiguracją zapisaną w pliku config.neon
:
$loader = new Nette\DI\ContainerLoader(__DIR__ . '/temp');
$class = $loader->load(function ($compiler) {
$compiler->loadConfig(__DIR__ . '/config.neon');
});
$container = new $class;
Kontener generuje się tylko raz, jego kod zapisuje się do cache (katalog __DIR__ . '/temp'
) i przy kolejnych
żądaniach jest już tylko stamtąd odczytywany.
Do tworzenia i pobierania usług służą metody getService()
lub getByType()
. W ten sposób
utworzymy obiekt UserController
:
$controller = $container->getByType(UserController::class);
$controller->someMethod();
Podczas rozwoju przydatne jest aktywowanie trybu auto-refresh, w którym kontener automatycznie się przgeneruje, jeśli
dojdzie do zmiany jakiejkolwiek klasy lub pliku konfiguracyjnego. Wystarczy w konstruktorze ContainerLoader
podać
jako drugi argument true
.
$loader = new Nette\DI\ContainerLoader(__DIR__ . '/temp', true);
Użycie z frameworkiem Nette
Jak pokazaliśmy, użycie Nette DI nie jest ograniczone do aplikacji pisanych w Nette Framework, możesz go za pomocą zaledwie 3 linii kodu wdrożyć gdziekolwiek. Jeśli jednak rozwijasz aplikacje w Nette Framework, konfigurację i tworzenie kontenera ma na starcie Bootstrap.