Ορισμοί υπηρεσιών
Η διαμόρφωση είναι το σημείο όπου τοποθετούμε τους ορισμούς
των προσαρμοσμένων υπηρεσιών. Αυτό γίνεται στην ενότητα services
.
Για παράδειγμα, έτσι δημιουργούμε μια υπηρεσία με το όνομα
database
, η οποία θα είναι μια περίπτωση της κλάσης PDO
:
services:
database: PDO('sqlite::memory:')
Η ονοματοδοσία των υπηρεσιών χρησιμοποιείται για να μας επιτρέπει να τις αναφέρουμε. Εάν μια υπηρεσία δεν αναφέρεται, δεν υπάρχει λόγος να την ονομάσουμε. Έτσι, αντί για όνομα χρησιμοποιούμε απλώς ένα σημείο αναφοράς:
services:
- PDO('sqlite::memory:') # ανώνυμη υπηρεσία
Μια καταχώρηση μιας γραμμής μπορεί να σπάσει σε πολλές γραμμές για να
επιτραπεί η προσθήκη πρόσθετων κλειδιών, όπως το setup. Το
ψευδώνυμο για το κλειδί create:
είναι factory:
.
services:
database:
create: PDO('sqlite::memory:')
setup: ...
Στη συνέχεια, ανακτούμε την υπηρεσία από το δοχείο DI χρησιμοποιώντας
τη μέθοδο getService()
με βάση το όνομα ή, ακόμα καλύτερα, τη μέθοδο
getByType()
με βάση τον τύπο:
$database = $container->getService('database');
$database = $container->getByType(PDO::class);
Δημιουργία υπηρεσίας
Τις περισσότερες φορές, δημιουργούμε μια υπηρεσία με την απλή δημιουργία μιας περίπτωσης μιας κλάσης:
services:
database: PDO('mysql:host=127.0.0.1;dbname=test', root, secret)
Η οποία θα δημιουργήσει μια μέθοδο εργοστασίου στο DI container:
public function createServiceDatabase(): PDO
{
return new PDO('mysql:host=127.0.0.1;dbname=test', 'root', 'secret');
}
Εναλλακτικά, ένα κλειδί arguments
μπορεί να χρησιμοποιηθεί για να
περάσει ορίσματα:
services:
database:
create: PDO
arguments: ['mysql:host=127.0.0.1;dbname=test', root, secret]
Μια στατική μέθοδος μπορεί επίσης να δημιουργήσει μια υπηρεσία:
services:
database: My\Database::create(root, secret)
Αντιστοιχεί στον κώδικα PHP:
public function createServiceDatabase(): PDO
{
return My\Database::create('root', 'secret');
}
Μια στατική μέθοδος My\Database::create()
θεωρείται ότι έχει
καθορισμένη τιμή επιστροφής που πρέπει να γνωρίζει ο περιέκτης DI. Εάν
δεν την έχει, γράφουμε τον τύπο στη διαμόρφωση:
services:
database:
create: My\Database::create(root, secret)
type: PDO
Η Nette DI σας δίνει εξαιρετικά ισχυρές δυνατότητες έκφρασης για να
γράψετε σχεδόν οτιδήποτε. Για παράδειγμα, για να αναφερθούμε σε μια άλλη υπηρεσία και να καλέσουμε
τη μέθοδό της. Για λόγους απλότητας, χρησιμοποιείται το ::
αντί
του ->
.
services:
routerFactory: App\Router\Factory
router: @routerFactory::create()
Αντιστοιχεί σε κώδικα PHP:
public function createServiceRouterFactory(): App\Router\Factory
{
return new App\Router\Factory;
}
public function createServiceRouter(): Router
{
return $this->getService('routerFactory')->create();
}
Οι κλήσεις μεθόδων μπορούν να συνδεθούν αλυσιδωτά όπως στην PHP:
services:
foo: FooFactory::build()::get()
Αντιστοιχεί στον κώδικα PHP:
public function createServiceFoo()
{
return FooFactory::build()->get();
}
Επιχειρήματα
Οι ονομαστικές παράμετροι μπορούν επίσης να χρησιμοποιηθούν για τη μετάδοση επιχειρημάτων:
services:
database: PDO(
'mysql:host=127.0.0.1;dbname=test' # θέση
username: root # όνομα
password: secret # named
)
Η χρήση των κομμάτων είναι προαιρετική όταν τα ορίσματα χωρίζονται σε πολλές γραμμές.
Φυσικά, μπορούμε επίσης να χρησιμοποιήσουμε άλλες υπηρεσίες ή παραμέτρους ως ορίσματα:
services:
- Foo(@anotherService, %appDir%)
Αντιστοιχεί στον κώδικα PHP:
public function createService01(): Foo
{
return new Foo($this->getService('anotherService'), '...');
}
_
character, for example Foo(_, %appDir%)
Ή ακόμα καλύτερα, περάστε μόνο το
δεύτερο όρισμα ως ονομαστική παράμετρο, π.χ. Foo(path: %appDir%)
.
Το Nette DI και η μορφή NEON σας δίνουν εξαιρετικά ισχυρές εκφραστικές δυνατότητες για να γράψετε σχεδόν οτιδήποτε. Έτσι, ένα όρισμα μπορεί να είναι ένα νεοδημιουργημένο αντικείμενο, μπορείτε να καλέσετε στατικές μεθόδους, μεθόδους άλλων υπηρεσιών ή ακόμη και παγκόσμιες συναρτήσεις χρησιμοποιώντας ειδικό συμβολισμό:
services:
analyser: My\Analyser(
FilesystemIterator(%appDir%) # δημιουργία αντικειμένου
DateTime::createFromFormat('Y-m-d') # κλήση στατικής μεθόδου
@anotherService # περνώντας μια άλλη υπηρεσία
@http.request::getRemoteAddress() # κλήση άλλης μεθόδου υπηρεσίας
::getenv(NetteMode) # κλήση παγκόσμιας συνάρτησης
)
Αντιστοιχεί στον κώδικα PHP:
public function createServiceAnalyser(): My\Analyser
{
return new My\Analyser(
new FilesystemIterator('...'),
DateTime::createFromFormat('Y-m-d'),
$this->getService('anotherService'),
$this->getService('http.request')->getRemoteAddress(),
getenv('NetteMode')
);
}
PHP: Ειδικές λειτουργίες
Μπορείτε επίσης να χρησιμοποιήσετε ειδικές συναρτήσεις σε ορίσματα για να ρίξετε ή να αναιρέσετε τιμές:
not(%arg%)
negationbool(%arg%)
cast χωρίς απώλειες σε boolint(%arg%)
cast χωρίς απώλειες σε intfloat(%arg%)
lossless cast to floatstring(%arg%)
lossless cast to string
services:
- Foo(
id: int(::getenv('ProjectId'))
productionMode: not(%debugMode%)
)
Η αναδιαγραφή χωρίς απώλειες διαφέρει από την κανονική αναδιαγραφή
της PHP, π.χ. με τη χρήση του (int)
, στο ότι πετάει μια εξαίρεση για μη
αριθμητικές τιμές.
Πολλαπλές υπηρεσίες μπορούν να περάσουν ως ορίσματα. Ένας πίνακας
όλων των υπηρεσιών ενός συγκεκριμένου τύπου (δηλ. κλάσης ή διεπαφής)
δημιουργείται από τη συνάρτηση typed()
. Η συνάρτηση θα παραλείψει
τις υπηρεσίες που έχουν απενεργοποιήσει την αυτόματη καλωδίωση και
μπορούν να καθοριστούν πολλαπλοί τύποι που χωρίζονται με κόμμα.
services:
- BarsDependent( typed(Bar) )
Μπορείτε επίσης να περάσετε έναν πίνακα υπηρεσιών αυτόματα χρησιμοποιώντας την αυτόματη καλωδίωση.
Ένας πίνακας όλων των υπηρεσιών με μια συγκεκριμένη ετικέτα δημιουργείται από τη συνάρτηση tagged()
.
Μπορούν να καθοριστούν πολλαπλές ετικέτες που χωρίζονται με κόμμα.
services:
- LoggersDependent( tagged(logger) )
Αναφορά σε υπηρεσίες
Η αναφορά σε μεμονωμένες υπηρεσίες γίνεται με τη χρήση των
χαρακτήρων @
and name, so for example @database
:
services:
- create: Foo(@database)
setup:
- setCacheStorage(@cache.storage)
Αντιστοιχεί στον κώδικα PHP:
public function createService01(): Foo
{
$service = new Foo($this->getService('database'));
$service->setCacheStorage($this->getService('cache.storage'));
return $service;
}
Ακόμα και ανώνυμες υπηρεσίες μπορούν να αναφερθούν χρησιμοποιώντας μια επανάκληση, απλά καθορίστε τον τύπο τους (κλάση ή διεπαφή) αντί για το όνομά τους. Ωστόσο, αυτό συνήθως δεν είναι απαραίτητο λόγω της αυτόματης καλωδίωσης.
services:
- create: Foo(@Nette\Database\Connection) # ή @\PDO
setup:
- setCacheStorage(@cache.storage)
Ρύθμιση
Στην ενότητα setup παραθέτουμε τις μεθόδους που θα κληθούν κατά τη δημιουργία της υπηρεσίας:
services:
database:
create: PDO(%dsn%, %user%, %password%)
setup:
- setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION)
Αντιστοιχεί στον κώδικα PHP:
public function createServiceDatabase(): PDO
{
$service = new PDO('...', '...', '...');
$service->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $service;
}
Properites μπορεί επίσης να οριστεί. Η προσθήκη ενός στοιχείου σε έναν πίνακα υποστηρίζεται επίσης, και θα πρέπει να γράφεται σε εισαγωγικά για να μην έρχεται σε σύγκρουση με τη σύνταξη του NEON:
services:
foo:
create: Foo
setup:
- $value = 123
- '$onClick[]' = [@bar, clickHandler]
Αντιστοιχεί στον κώδικα PHP:
public function createServiceFoo(): Foo
{
$service = new Foo;
$service->value = 123;
$service->onClick[] = [$this->getService('bar'), 'clickHandler'];
return $service;
}
Ωστόσο, οι στατικές μέθοδοι ή οι μέθοδοι άλλων υπηρεσιών μπορούν
επίσης να κληθούν στη ρύθμιση. Τους περνάμε την πραγματική υπηρεσία ως
@self
:
services:
foo:
create: Foo
setup:
- My\Helpers::initializeFoo(@self)
- @anotherService::setFoo(@self)
Αντιστοιχεί στον κώδικα PHP:
public function createServiceFoo(): Foo
{
$service = new Foo;
My\Helpers::initializeFoo($service);
$this->getService('anotherService')->setFoo($service);
return $service;
}
Autowiring
Το κλειδί autowired μπορεί να χρησιμοποιηθεί για να αποκλείσει μια υπηρεσία από την αυτόματη σύνδεση ή για να επηρεάσει τη συμπεριφορά της. Για περισσότερες πληροφορίες, ανατρέξτε στο κεφάλαιο σχετικά με την αυτόματη σύνδεση.
services:
foo:
create: Foo
autowired: false # Το foo αφαιρείται από την αυτόματη καλωδίωση
Ετικέτες
Οι πληροφορίες χρήστη μπορούν να προστεθούν σε μεμονωμένες υπηρεσίες με τη μορφή ετικετών:
services:
foo:
create: Foo
tags:
- cached
Οι ετικέτες μπορούν επίσης να έχουν μια τιμή:
services:
foo:
create: Foo
tags:
logger: monolog.logger.event
Ένας πίνακας υπηρεσιών με συγκεκριμένες ετικέτες μπορεί να περάσει
ως όρισμα χρησιμοποιώντας τη συνάρτηση tagged()
. Μπορούν επίσης να
καθοριστούν πολλαπλές ετικέτες που χωρίζονται με κόμμα.
services:
- LoggersDependent( tagged(logger) )
Τα ονόματα των υπηρεσιών μπορούν να ληφθούν από το δοχείο DI
χρησιμοποιώντας τη μέθοδο findByTag()
:
$names = $container->findByTag('logger');
// $names είναι ένας πίνακας που περιέχει το όνομα της υπηρεσίας και την τιμή της ετικέτας
// π.χ. ['foo' => 'monolog.logger.event', ...]
Inject Mode
Η σημαία inject: true
χρησιμοποιείται για την ενεργοποίηση του
περάσματος εξαρτήσεων μέσω δημόσιων μεταβλητών με τον σχολιασμό inject και τις
μεθόδους inject*().
services:
articles:
create: App\Model\Articles
inject: true
Από προεπιλογή, το inject
είναι ενεργοποιημένο μόνο για τους
παρουσιαστές.
Τροποποίηση των υπηρεσιών
Υπάρχει ένας αριθμός υπηρεσιών στο δοχείο DI που έχουν προστεθεί από
ενσωματωμένο ή από την επέκτασή σας. Οι ορισμοί αυτών
των υπηρεσιών μπορούν να τροποποιηθούν στη διαμόρφωση. Για παράδειγμα,
για την υπηρεσία application.application
, η οποία είναι εξ ορισμού ένα
αντικείμενο Nette\Application\Application
, μπορούμε να αλλάξουμε
την κλάση:
services:
application.application:
create: MyApplication
alteration: true
Η σημαία alteration
είναι πληροφοριακή και δηλώνει ότι απλώς
τροποποιούμε μια υπάρχουσα υπηρεσία.
Μπορούμε επίσης να προσθέσουμε μια ρύθμιση:
services:
application.application:
create: MyApplication
alteration: true
setup:
- '$onStartup[]' = [@resource, init]
Γι' αυτό υπάρχει το reset
:
services:
application.application:
create: MyApplication
alteration: true
reset:
- arguments
- setup
- tags
Μια υπηρεσία που προστίθεται με επέκταση μπορεί επίσης να αφαιρεθεί από το δοχείο:
services:
cache.journal: false