Διαμόρφωση του DI Container
Επισκόπηση των επιλογών διαμόρφωσης για το Nette DI Container.
Αρχείο διαμόρφωσης
Το Nette DI Container ελέγχεται εύκολα μέσω αρχείων διαμόρφωσης. Αυτά συνήθως γράφονται σε μορφή NEON. Για την επεξεργασία, συνιστούμε editors με υποστήριξη αυτής της μορφής.
decorator: Decorator
di: DI container
extensions: Εγκατάσταση πρόσθετων επεκτάσεων DI
includes: Εισαγωγή αρχείων
parameters: Παράμετροι
search: Αυτόματη καταχώρηση υπηρεσιών
services: Υπηρεσίες
Για να γράψετε μια συμβολοσειρά που περιέχει τον χαρακτήρα
%
, πρέπει να τον διαφύγετε διπλασιάζοντάς τον σε %%
.
Παράμετροι
Στη διαμόρφωση, μπορείτε να ορίσετε παραμέτρους που μπορούν στη συνέχεια να χρησιμοποιηθούν ως μέρος των ορισμών υπηρεσιών. Με αυτόν τον τρόπο, μπορείτε να κάνετε τη διαμόρφωση πιο σαφή ή να ενοποιήσετε και να απομονώσετε τιμές που θα αλλάξουν.
parameters:
dsn: 'mysql:host=127.0.0.1;dbname=test'
user: root
password: secret
Αναφερόμαστε στην παράμετρο dsn
οπουδήποτε στη διαμόρφωση
γράφοντας %dsn%
. Οι παράμετροι μπορούν να χρησιμοποιηθούν και
μέσα σε συμβολοσειρές όπως '%wwwDir%/images'
.
Οι παράμετροι δεν χρειάζεται να είναι μόνο συμβολοσειρές ή αριθμοί, μπορούν επίσης να περιέχουν πίνακες:
parameters:
mailer:
host: smtp.example.com
secure: ssl
user: franta@gmail.com
languages: [cs, en, de]
Αναφερόμαστε σε ένα συγκεκριμένο κλειδί ως %mailer.user%
.
Εάν χρειάζεστε στον κώδικά σας, για παράδειγμα σε μια κλάση, να μάθετε την τιμή οποιασδήποτε παραμέτρου, τότε περάστε την σε αυτήν την κλάση. Για παράδειγμα, στον κατασκευαστή. Δεν υπάρχει κανένα καθολικό αντικείμενο που να αντιπροσωπεύει τη διαμόρφωση, το οποίο οι κλάσεις θα ρωτούσαν για τις τιμές των παραμέτρων. Αυτό θα παραβίαζε την αρχή του dependency injection.
Υπηρεσίες
Βλ. ξεχωριστό κεφάλαιο.
Decorator
Πώς να τροποποιήσετε μαζικά όλες τις υπηρεσίες ενός συγκεκριμένου τύπου; Για παράδειγμα, να καλέσετε μια συγκεκριμένη μέθοδο σε όλους τους presenters που κληρονομούν από έναν συγκεκριμένο κοινό πρόγονο? Γι' αυτό υπάρχει ο decorator.
decorator:
# για όλες τις υπηρεσίες που είναι παρουσίες αυτής της κλάσης ή interface
App\Presentation\BasePresenter:
setup:
- setProjectId(10) # καλέστε αυτή τη μέθοδο
- $absoluteUrls = true # και ορίστε τη μεταβλητή
Ο decorator μπορεί επίσης να χρησιμοποιηθεί για τον ορισμό tags ή την ενεργοποίηση της λειτουργίας inject.
decorator:
InjectableInterface:
tags: [mytag: 1]
inject: true
DI
Τεχνικές ρυθμίσεις του DI container.
di:
# εμφάνιση του DIC στο Tracy Bar;
debugger: ... # (bool) η προεπιλογή είναι true
# τύποι παραμέτρων που δεν γίνονται ποτέ autowired
excluded: ... # (string[])
# επιτρέπεται η lazy δημιουργία υπηρεσιών;
lazy: ... # (bool) η προεπιλογή είναι false
# κλάση από την οποία κληρονομεί το DI container
parentClass: ... # (string) η προεπιλογή είναι Nette\DI\Container
Lazy υπηρεσίες
Η ρύθμιση lazy: true
ενεργοποιεί τη lazy (καθυστερημένη) δημιουργία
υπηρεσιών. Αυτό σημαίνει ότι οι υπηρεσίες δεν δημιουργούνται
πραγματικά τη στιγμή που τις ζητάμε από το DI container, αλλά τη στιγμή της
πρώτης τους χρήσης. Αυτό μπορεί να επιταχύνει την εκκίνηση της
εφαρμογής και να μειώσει τις απαιτήσεις μνήμης, καθώς δημιουργούνται
μόνο οι υπηρεσίες που είναι πραγματικά απαραίτητες στο συγκεκριμένο
request.
Για μια συγκεκριμένη υπηρεσία, η lazy δημιουργία μπορεί να αλλάξει.
Τα lazy αντικείμενα μπορούν να χρησιμοποιηθούν μόνο για κλάσεις χρήστη, όχι για εσωτερικές κλάσεις PHP. Απαιτεί PHP 8.4 ή νεότερη έκδοση.
Εξαγωγή μεταδεδομένων
Η κλάση του DI container περιέχει επίσης πολλά μεταδεδομένα. Μπορείτε να τη μειώσετε περιορίζοντας την εξαγωγή μεταδεδομένων.
di:
export:
# εξαγωγή παραμέτρων;
parameters: false # (bool) η προεπιλογή είναι true
# εξαγωγή tags και ποια;
tags: # (string[]|bool) η προεπιλογή είναι όλα
- event.subscriber
# εξαγωγή δεδομένων για autowiring και ποια;
types: # (string[]|bool) η προεπιλογή είναι όλα
- Nette\Database\Connection
- Symfony\Component\Console\Application
Εάν δεν χρησιμοποιείτε τον πίνακα $container->getParameters()
, μπορείτε
να απενεργοποιήσετε την εξαγωγή παραμέτρων. Επιπλέον, μπορείτε να
εξάγετε μόνο τα tags μέσω των οποίων λαμβάνετε υπηρεσίες με τη μέθοδο
$container->findByTag(...)
. Εάν δεν καλείτε καθόλου τη μέθοδο, μπορείτε να
απενεργοποιήσετε εντελώς την εξαγωγή tags χρησιμοποιώντας false
.
Μπορείτε να μειώσετε σημαντικά τα μεταδεδομένα για autowiring αναφέροντας τις κλάσεις που
χρησιμοποιείτε ως παράμετρο της μεθόδου $container->getByType()
. Και
πάλι, εάν δεν καλείτε καθόλου τη μέθοδο (ή μόνο στο bootstrap για να λάβετε το
Nette\Application\Application
), μπορείτε να απενεργοποιήσετε εντελώς την
εξαγωγή χρησιμοποιώντας false
.
Επεκτάσεις
Καταχώρηση πρόσθετων επεκτάσεων DI. Με αυτόν τον τρόπο προσθέτουμε,
για παράδειγμα, την επέκταση DI Dibi\Bridges\Nette\DibiExtension22
με το
όνομα dibi
extensions:
dibi: Dibi\Bridges\Nette\DibiExtension22
Στη συνέχεια, τη διαμορφώνουμε στην ενότητα dibi
:
dibi:
host: localhost
Ως επέκταση μπορεί να προστεθεί και μια κλάση που έχει παραμέτρους:
extensions:
application: Nette\Bridges\ApplicationDI\ApplicationExtension(%debugMode%, %appDir%, %tempDir%/cache)
Εισαγωγή αρχείων
Μπορούμε να εισάγουμε άλλα αρχεία διαμόρφωσης στην ενότητα
includes
:
includes:
- parameters.php
- services.neon
- presenters.neon
Το όνομα parameters.php
δεν είναι τυπογραφικό λάθος, η διαμόρφωση
μπορεί επίσης να γραφτεί σε ένα αρχείο PHP, το οποίο την επιστρέφει ως
πίνακα:
<?php
return [
'database' => [
'main' => [
'dsn' => 'sqlite::memory:',
],
],
];
Εάν εμφανιστούν στοιχεία με τα ίδια κλειδιά σε αρχεία διαμόρφωσης, θα
αντικατασταθούν ή, στην περίπτωση πινάκων, θα
συγχωνευθούν. Το αρχείο που εισάγεται αργότερα έχει υψηλότερη
προτεραιότητα από το προηγούμενο. Το αρχείο στο οποίο αναφέρεται η
ενότητα includes
έχει υψηλότερη προτεραιότητα από τα αρχεία που
εισάγονται σε αυτό.
Αναζήτηση
Η αυτόματη προσθήκη υπηρεσιών στο DI container διευκολύνει εξαιρετικά την εργασία. Το Nette προσθέτει αυτόματα presenters στο container, αλλά μπορεί εύκολα να προσθέσει και οποιεσδήποτε άλλες κλάσεις.
Αρκεί να αναφέρετε σε ποιους καταλόγους (και υποκαταλόγους) πρέπει να αναζητήσει κλάσεις:
search:
- in: %appDir%/Forms
- in: %appDir%/Model
Συνήθως, όμως, δεν θέλουμε να προσθέσουμε απολύτως όλες τις κλάσεις και τα interfaces, γι' αυτό μπορούμε να τα φιλτράρουμε:
search:
- in: %appDir%/Forms
# φιλτράρισμα με βάση το όνομα αρχείου (string|string[])
files:
- *Factory.php
# φιλτράρισμα με βάση το όνομα κλάσης (string|string[])
classes:
- *Factory
Ή μπορούμε να επιλέξουμε κλάσεις που κληρονομούν ή υλοποιούν τουλάχιστον μία από τις αναφερόμενες κλάσεις:
search:
- in: %appDir%
extends:
- App\*Form
implements:
- App\*FormInterface
Μπορούν επίσης να οριστούν κανόνες εξαίρεσης, δηλ. μάσκες ονόματος κλάσης ή κληρονομικοί πρόγονοι, που εάν ταιριάζουν, η υπηρεσία δεν προστίθεται στο DI container:
search:
- in: %appDir%
exclude:
files: ...
classes: ...
extends: ...
implements: ...
Σε όλες τις υπηρεσίες μπορούν να οριστούν tags:
search:
- in: %appDir%
tags: ...
Συγχώνευση
Εάν εμφανιστούν στοιχεία με τα ίδια κλειδιά σε περισσότερα αρχεία διαμόρφωσης, θα αντικατασταθούν ή, στην περίπτωση πινάκων, θα συγχωνευθούν. Το αρχείο που εισάγεται αργότερα έχει υψηλότερη προτεραιότητα από το προηγούμενο.
config1.neon | config2.neon | αποτέλεσμα |
---|---|---|
|
|
|
Στους πίνακες, η συγχώνευση μπορεί να αποτραπεί αναφέροντας ένα θαυμαστικό μετά το όνομα του κλειδιού:
config1.neon | config2.neon | αποτέλεσμα |
---|---|---|
|
|
|