Nette DI Container
Το Nette DI είναι μία από τις πιο ενδιαφέρουσες βιβλιοθήκες του Nette. Μπορεί να δημιουργεί και να ενημερώνει αυτόματα μεταγλωττισμένα DI containers, τα οποία είναι εξαιρετικά γρήγορα και εκπληκτικά εύκολα στη διαμόρφωση.
Τη μορφή των υπηρεσιών που πρόκειται να δημιουργήσει το DI container την ορίζουμε συνήθως χρησιμοποιώντας αρχεία διαμόρφωσης σε μορφή NEON. Το container που δημιουργήσαμε χειροκίνητα στο προηγούμενο κεφάλαιο, θα γραφόταν ως εξής:
parameters:
db:
dsn: 'mysql:'
user: root
password: '***'
services:
- Nette\Database\Connection(%db.dsn%, %db.user%, %db.password%)
- ArticleFactory
- UserController
Η σύνταξη είναι πραγματικά συνοπτική.
Όλες οι εξαρτήσεις που δηλώνονται στους κατασκευαστές των κλάσεων
ArticleFactory
και UserController
, το Nette DI τις βρίσκει και τις
παραδίδει αυτόματα χάρη στο λεγόμενο autowiring, επομένως δεν χρειάζεται να
δηλωθεί τίποτα στο αρχείο διαμόρφωσης. Έτσι, ακόμα κι αν αλλάξουν οι
παράμετροι, δεν χρειάζεται να αλλάξετε τίποτα στη διαμόρφωση. Το Nette
container θα αναδημιουργηθεί αυτόματα. Μπορείτε να επικεντρωθείτε
αποκλειστικά στην ανάπτυξη της εφαρμογής.
Αν θέλουμε να παραδώσουμε εξαρτήσεις χρησιμοποιώντας setters, χρησιμοποιούμε την ενότητα setup για αυτό.
Το Nette DI παράγει απευθείας τον κώδικα PHP του container. Το αποτέλεσμα είναι
λοιπόν ένα αρχείο .php
, το οποίο μπορείτε να ανοίξετε και να
μελετήσετε. Χάρη σε αυτό, βλέπετε ακριβώς πώς λειτουργεί το container.
Μπορείτε επίσης να το κάνετε debug στο IDE και να το εκτελέσετε βήμα-βήμα.
Και κυρίως: ο παραγόμενος κώδικας PHP είναι εξαιρετικά γρήγορος.
Το Nette DI μπορεί επίσης να παράγει κώδικα για factories βάσει ενός παρεχόμενου interface.
Επομένως, αντί για την κλάση ArticleFactory
, θα αρκεί να δημιουργήσουμε
μόνο ένα interface στην εφαρμογή:
interface ArticleFactory
{
function create(): Article;
}
Ολόκληρο το παράδειγμα μπορείτε να το βρείτε στο GitHub.
Αυτόνομη χρήση
Η ενσωμάτωση της βιβλιοθήκης Nette DI σε μια εφαρμογή είναι πολύ εύκολη. Πρώτα την εγκαθιστούμε με το Composer (επειδή η λήψη zip είναι τόοοσο παλιομοδίτικη):
composer require nette/di
Ο παρακάτω κώδικας δημιουργεί μια παρουσία του DI container σύμφωνα με τη
διαμόρφωση που είναι αποθηκευμένη στο αρχείο config.neon
:
$loader = new Nette\DI\ContainerLoader(__DIR__ . '/temp');
$class = $loader->load(function ($compiler) {
$compiler->loadConfig(__DIR__ . '/config.neon');
});
$container = new $class;
Το container δημιουργείται μόνο μία φορά, ο κώδικας του γράφεται στην cache
(κατάλογος __DIR__ . '/temp'
) και στα επόμενα αιτήματα απλώς φορτώνεται
από εκεί.
Για τη δημιουργία και λήψη υπηρεσιών χρησιμοποιούνται οι μέθοδοι
getService()
ή getByType()
. Έτσι δημιουργούμε το αντικείμενο
UserController
:
$controller = $container->getByType(UserController::class);
$controller->someMethod();
Κατά την ανάπτυξη, είναι χρήσιμο να ενεργοποιήσετε τη λειτουργία
auto-refresh, όπου το container αναδημιουργείται αυτόματα εάν αλλάξει
οποιαδήποτε κλάση ή αρχείο διαμόρφωσης. Αρκεί να δώσετε true
ως
δεύτερο όρισμα στον κατασκευαστή ContainerLoader
.
$loader = new Nette\DI\ContainerLoader(__DIR__ . '/temp', true);
Χρήση με το Nette Framework
Όπως δείξαμε, η χρήση του Nette DI δεν περιορίζεται σε εφαρμογές γραμμένες στο Nette Framework, μπορείτε να το ενσωματώσετε οπουδήποτε με μόλις 3 γραμμές κώδικα. Ωστόσο, εάν αναπτύσσετε εφαρμογές στο Nette Framework, τη διαμόρφωση και τη δημιουργία του container την αναλαμβάνει το Bootstrap.