Szolgáltatás meghatározások

A konfigurációban helyezzük el az egyéni szolgáltatások definícióit. Ez a services szakaszban történik.

Például így hozunk létre egy database nevű szolgáltatást, amely a PDO osztály példánya lesz:

services:
	database: PDO('sqlite::memory:')

A szolgáltatások elnevezése arra szolgál, hogy hivatkozni tudjunk rájuk. Ha egy szolgáltatásra nem hivatkozunk, akkor nincs szükség nevet adni neki. Ezért a név helyett csak egy felsoroláspontot használunk:

services:
	- PDO('sqlite::memory:') # anonim szolgáltatás

Az egysoros bejegyzés több sorra bontható, hogy további kulcsokat lehessen hozzáadni, például setup. A create: billentyű álneve a factory:.

services:
	database:
		create: PDO('sqlite::memory:')
		setup: ...

Ezután a szolgáltatást a DI konténerből a getService() metódus segítségével hívjuk le név szerint, vagy még jobb esetben a getByType() metódus segítségével típus szerint:

$database = $container->getService('database');
$database = $container->getByType(PDO::class);

Szolgáltatás létrehozása

Leggyakrabban úgy hozunk létre egy szolgáltatást, hogy egyszerűen létrehozzuk egy osztály példányát:

services:
	database: PDO('mysql:host=127.0.0.1;dbname=test', root, secret)

Ami egy gyári metódust generál a DI konténerben:

public function createServiceDatabase(): PDO
{
	return new PDO('mysql:host=127.0.0.1;dbname=test', 'root', 'secret');
}

Alternatívaként egy kulcsot arguments lehet használni az argumentumok átadására:

services:
	database:
		create: PDO
		arguments: ['mysql:host=127.0.0.1;dbname=test', root, secret]

Egy statikus módszer is létrehozhat egy szolgáltatást:

services:
	database: My\Database::create(root, secret)

Megfelel a PHP-kódnak:

public function createServiceDatabase(): PDO
{
	return My\Database::create('root', 'secret');
}

Egy statikus metódus My\Database::create() feltételezhetően rendelkezik egy meghatározott visszatérési értékkel, amelyet a DI konténernek ismernie kell. Ha nem rendelkezik vele, akkor a típusát a konfigurációba írjuk:

services:
	database:
		create: My\Database::create(root, secret)
		type: PDO

A Nette DI rendkívül hatékony kifejezési lehetőségeket biztosít, amelyekkel szinte bármit leírhatunk. Például egy másik szolgáltatásra való hivatkozás és annak metódusának meghívása. Az egyszerűség kedvéért a -> helyett a :: -t használjuk.

services:
	routerFactory: App\Router\Factory
	router: @routerFactory::create()

Megfelel a PHP-kódnak:

public function createServiceRouterFactory(): App\Router\Factory
{
	return new App\Router\Factory;
}

public function createServiceRouter(): Router
{
	return $this->getService('routerFactory')->create();
}

A metódushívások a PHP-hez hasonlóan láncolhatók egymáshoz:

services:
	foo: FooFactory::build()::get()

Megfelel a PHP kódnak:

public function createServiceFoo()
{
	return FooFactory::build()->get();
}

Érvek:

A megnevezett paraméterek argumentumok átadására is használhatók:

services:
	database: PDO(
		'mysql:host=127.0.0.1;dbname=test'  # pozicionális
		username: root                      # named
		password: secret                    # named
	)

A vesszők használata opcionális, ha az argumentumokat több sorra bontjuk.

Természetesen más szolgáltatásokat vagy paramétereket is használhatunk argumentumként:

services:
	- Foo(@anotherService, %appDir%)

Megfelel a PHP-kódnak:

public function createService01(): Foo
{
	return new Foo($this->getService('anotherService'), '...');
}

_ character, for example Foo(_, %appDir%)Vagy még jobb, ha csak a második argumentumot adjuk át megnevezett paraméterként, pl. Foo(path: %appDir%).

A Nette DI és a NEON formátum rendkívül erőteljes kifejezési lehetőségeket biztosít szinte bármi megírásához. Így egy argumentum lehet egy újonnan létrehozott objektum, hívhat statikus metódusokat, más szolgáltatások metódusait, vagy akár globális függvényeket is, speciális jelölés használatával:

services:
	analyser: My\Analyser(
		FilesystemIterator(%appDir%)        # create object
		DateTime::createFromFormat('Y-m-d') # statikus metódus hívása
		@anotherService                     # egy másik szolgáltatás átadása
		@http.request::getRemoteAddress()   # egy másik szolgáltatás metódusának hívása
		::getenv(NetteMode)                 # globális függvény hívása
	)

Megfelel a PHP kódnak:

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')
	);
}

Speciális funkciók

Speciális függvényeket is használhat az argumentumokban értékek kiértékelésére vagy negálására:

  • not(%arg%) negáció
  • bool(%arg%) lossless cast to bool
  • int(%arg%) veszteségmentes átváltás int-re
  • float(%arg%) lossless cast to float
  • string(%arg%) lossless cast to string
services:
	- Foo(
		id: int(::getenv('ProjectId'))
		productionMode: not(%debugMode%)
	)

A veszteségmentes átírás abban különbözik a normál PHP átírástól, pl. a (int) használatával, hogy a nem numerikus értékek esetén kivételt dob.

Több szolgáltatás is átadható argumentumként. Egy adott típusú (azaz osztály vagy interfész) összes szolgáltatásának tömbjét a typed() függvény hozza létre. A függvény kihagyja azokat a szolgáltatásokat, amelyeknél az automatikus kapcsolás ki van kapcsolva, és több típus is megadható vesszővel elválasztva.

services:
	- BarsDependent( typed(Bar) )

A szolgáltatások tömbjét automatikusan is átadhatja az automatikus bekötés segítségével.

A tagged() függvény létrehozza az összes, egy adott címkével rendelkező szolgáltatás tömbjét. Több, vesszővel elválasztott címke is megadható.

services:
	- LoggersDependent( tagged(logger) )

Szolgáltatásokra való hivatkozás

Az egyes szolgáltatásokra a @ and name, so for example @database karakterek segítségével lehet hivatkozni:

services:
	- create: Foo(@database)
	  setup:
			- setCacheStorage(@cache.storage)

Megfelel a PHP kódnak:

public function createService01(): Foo
{
	$service = new Foo($this->getService('database'));
	$service->setCacheStorage($this->getService('cache.storage'));
	return $service;
}

A névtelen szolgáltatásokra is lehet hivatkozni visszahívással, csak a típusukat (osztály vagy interfész) kell megadni a nevük helyett. Erre azonban az autowiring miatt általában nincs szükség.

services:
	- create: Foo(@Nette\Database\Connection)  # or @\PDO
	  setup:
			- setCacheStorage(@cache.storage)

Beállítás

A setup szakaszban felsoroljuk a szolgáltatás létrehozásakor meghívandó metódusokat:

services:
	database:
		create: PDO(%dsn%, %user%, %password%)
		setup:
			- setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION)

Megfelel a PHP-kódnak:

public function createServiceDatabase(): PDO
{
	$service = new PDO('...', '...', '...');
	$service->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
	return $service;
}

Properites is beállítható. Egy elem hozzáadása egy tömbhöz szintén támogatott, és idézőjelek közé kell írni, hogy ne ütközzön a NEON szintaxissal:

services:
	foo:
		create: Foo
		setup:
			- $value = 123
			- '$onClick[]' = [@bar, clickHandler]

Megfelel a PHP-kódnak:

public function createServiceFoo(): Foo
{
	$service = new Foo;
	$service->value = 123;
	$service->onClick[] = [$this->getService('bar'), 'clickHandler'];
	return $service;
}

A beállításban azonban statikus metódusok vagy más szolgáltatások metódusai is meghívhatók. Az aktuális szolgáltatást a @self címen adjuk át nekik:

services:
	foo:
		create: Foo
		setup:
			- My\Helpers::initializeFoo(@self)
			- @anotherService::setFoo(@self)

Megfelel a PHP kódnak:

public function createServiceFoo(): Foo
{
	$service = new Foo;
	My\Helpers::initializeFoo($service);
	$this->getService('anotherService')->setFoo($service);
	return $service;
}

Autowiring

Az autowired kulccsal kizárható egy szolgáltatás az autowiringből, vagy befolyásolható a viselkedése. További információért lásd az autowiring fejezetet.

services:
	foo:
		create: Foo
		autowired: false       # foo-t eltávolítjuk az autowiringből

Címkék

A felhasználói információk címkék formájában adhatók hozzá az egyes szolgáltatásokhoz:

services:
	foo:
		create: Foo
		tags:
			- cached

A címkéknek lehet értékük is:

services:
	foo:
		create: Foo
		tags:
			logger: monolog.logger.event

A tagged() függvény segítségével bizonyos címkékkel rendelkező szolgáltatások tömbje adható át argumentumként. Több, vesszővel elválasztott címke is megadható.

services:
	- LoggersDependent( tagged(logger) )

A szolgáltatások nevei a DI konténerből a findByTag() módszerrel szerezhetők be:

$names = $container->findByTag('logger');
// $names egy tömb, amely a szolgáltatás nevét és a tag értékét tartalmazza.
// pl. ['foo' => 'monolog.logger.event', ...]

Inject Mode

A inject: true flag a függőségek nyilvános változókon keresztüli átadásának aktiválására szolgál az inject annotációval és az inject*() metódusokkal.

services:
	articles:
		create: App\Model\Articles
		inject: true

Alapértelmezés szerint a inject csak az előadók esetében van aktiválva.

A szolgáltatások módosítása

A DI konténerben számos olyan szolgáltatás van, amelyet beépített vagy a bővítménye adott hozzá. Ezeknek a szolgáltatásoknak a definíciói a konfigurációban módosíthatók. Például a application.application szolgáltatás esetében, amely alapértelmezés szerint egy Nette\Application\Application objektum, megváltoztathatjuk az osztályt:

services:
	application.application:
		create: MyApplication
		alteration: true

A alteration jelző tájékoztató jellegű, és azt mondja, hogy csak egy meglévő szolgáltatást módosítunk.

Hozzáadhatunk egy beállítást is:

services:
	application.application:
		create: MyApplication
		alteration: true
		setup:
			- '$onStartup[]' = [@resource, init]

Erre való a reset:

services:
	application.application:
		create: MyApplication
		alteration: true
		reset:
			- arguments
			- setup
			- tags

A kiterjesztéssel hozzáadott szolgáltatás is eltávolítható a konténerből:

services:
	cache.journal: false
verzió: 3.x