Ορισμοί υπηρεσιών

Η διαμόρφωση είναι το σημείο όπου τοποθετούμε τους ορισμούς των προσαρμοσμένων υπηρεσιών. Αυτό γίνεται στην ενότητα 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%) negation
  • bool(%arg%) cast χωρίς απώλειες σε bool
  • int(%arg%) cast χωρίς απώλειες σε int
  • float(%arg%) lossless cast to float
  • string(%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
έκδοση: 3.x