Opredelitve storitev

Konfiguracija je mesto, kamor postavimo opredelitve storitev po meri. To storimo v razdelku services.

Tako na primer ustvarimo storitev z imenom database, ki bo primerek razreda PDO:

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

Poimenovanje storitev se uporablja zato, da se lahko nanje sklicujemo. Če se na storitev ne sklicujemo, je ni treba poimenovati. Zato namesto imena uporabimo le točko:

services:
	- PDO('sqlite::memory:')  # anonimna storitev

Enovrstični vnos lahko razdelimo v več vrstic, da lahko dodamo dodatne tipke, kot je nastavitev. Vzdevek za ključ create: je factory:.

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

Storitev nato prikličemo iz vsebnika DI z metodo getService() po imenu ali, še bolje, z metodo getByType() po vrsti:

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

Ustvarjanje storitve

Storitev najpogosteje ustvarimo tako, da preprosto ustvarimo primerek razreda:

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

To ustvari tovarniško metodo v vsebniku DI:

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

Za posredovanje argumentov se lahko uporabi tudi ključ arguments:

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

Statična metoda lahko ustvari tudi storitev:

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

Ustreza kodi PHP:

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

Predpostavlja se, da ima statična metoda My\Database::create() določeno povratno vrednost, ki jo mora vsebnik DI poznati. Če je nima, zapišemo tip v konfiguracijo:

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

Nette DI vam omogoča izjemno zmogljive izrazne zmogljivosti za zapisovanje skoraj vsega. Na primer za sklicevanje na drugo storitev in klic njene metode. Zaradi enostavnosti se namesto -> uporablja ::.

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

Ustreza kodi PHP:

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

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

klice metod je mogoče verižno povezati kot v PHP:

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

Ustreza kodi PHP:

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

Argumenti

Poimenovane parametre lahko uporabite tudi za posredovanje argumentov:

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

Uporaba vejic ni obvezna, če se argumenti razdelijo v več vrstic.

Seveda lahko kot argumente uporabimo tudi druge storitve ali parametre:

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

Ustreza kodi PHP:

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

Če je prvi argument samodejen in želite navesti drugega, izpustite prvega z _ character, for example Foo(_, %appDir%). Ali še bolje, samo drugi argument predajte kot poimenovani parameter, npr. Foo(path: %appDir%).

Nette DI in format NEON vam omogočata izjemno močne izrazne možnosti za zapisovanje skoraj vsega. Tako je lahko argument novo ustvarjen objekt, s posebnim zapisom lahko kličete statične metode, metode drugih storitev ali celo globalne funkcije:

services:
	analyser: My\Analyser(
		FilesystemIterator(%appDir%)         # ustvariti predmet
		DateTime::createFromFormat('Y-m-d')  # klic statične metode
		@anotherService                      # posredovanje druge storitve
		@http.request::getRemoteAddress()    # klic druge metode storitve
		::getenv(NetteMode)                  # klic globalne funkcije
	)

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

Posebne funkcije

Posebne funkcije lahko uporabite tudi v argumentih za izločanje ali zanikanje vrednosti:

  • not(%arg%) zanikanje
  • bool(%arg%) brez izgub odlitek v bool
  • int(%arg%) brez izgub v int
  • float(%arg%) brez izgub v float
  • string(%arg%) brez izgube v niz
services:
	- Foo(
		id: int(::getenv('ProjectId'))
		productionMode: not(%debugMode%)
	)

Brezizgubno prepisovanje se razlikuje od običajnega prepisovanja v PHP, npr. z uporabo (int), po tem, da vrže izjemo za neštevilčne vrednosti.

Kot argumente je mogoče posredovati več storitev. Polje vseh storitev določene vrste (tj. razreda ali vmesnika) ustvari funkcija typed(). Funkcija bo izpustila storitve, ki imajo onemogočeno samodejno napeljavo, lahko pa se določi več vrst, ločenih z vejico.

services:
	- BarsDependent( typed(Bar) )

Polje storitev lahko posredujete tudi samodejno z uporabo samodejnega napeljevanja.

Polje vseh storitev z določeno oznako ustvari funkcija tagged(). Navedete lahko več oznak, ločenih z vejico.

services:
	- LoggersDependent( tagged(logger) )

Sklicevanje na storitve

Na posamezne storitve se sklicujemo z uporabo znakov @ and name, so for example @database:

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

Ustreza kodi PHP:

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

Tudi na anonimne storitve se lahko sklicujete s povratnim klicem, le namesto imena navedite njihovo vrsto (razred ali vmesnik). Vendar to običajno ni potrebno zaradi samodejnega povezovanja.

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

Nastavitev

V razdelku nastavitev so naštete metode, ki jih je treba poklicati pri ustvarjanju storitve:

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

Ustreza kodi PHP:

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

Nastavite lahko tudi lastnosti. Podprto je tudi dodajanje elementa v polje, ki ga je treba zapisati v narekovajih, da ne bo v nasprotju s sintakso NEON:

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

Ustreza kodi PHP:

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

Vendar pa se lahko v nastavitvi kličejo tudi statične metode ali metode drugih storitev. Dejansko storitev jim posredujemo kot @self:

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

Ustreza kodi PHP:

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

Avtomatska napeljava

Ključ za samodejno ožičenje lahko uporabite za izključitev storitve iz samodejnega ožičenja ali za vplivanje na njeno obnašanje. Za več informacij glejte poglavje o samodejnem ožičenju.

services:
	foo:
		create: Foo
		autowired: false     # foo je odstranjen iz samodejne napeljave

Oznake

Posameznim storitvam je mogoče dodati informacije o uporabniku v obliki oznak:

services:
	foo:
		create: Foo
		tags:
			- cached

Oznake imajo lahko tudi vrednost:

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

Polje storitev z določenimi oznakami lahko posredujete kot argument s funkcijo tagged(). Določite lahko tudi več oznak, ki so ločene z vejico.

services:
	- LoggersDependent( tagged(logger) )

Imena storitev je mogoče pridobiti iz vsebnika DI z uporabo metode findByTag():

$names = $container->findByTag('logger');
// $names je polje, ki vsebuje ime storitve in vrednost oznake
// npr. ['foo' => 'monolog.logger.event', ...]

Inject Mode

Z zastavico inject: true se aktivira posredovanje odvisnosti prek javnih spremenljivk z opombo inject in metodami inject*( ).

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

Privzeto je funkcija inject aktivirana samo za predstavnike.

Spreminjanje storitev

V vsebniku DI so številne storitve, ki jih je dodala vgrajena ali vaša razširitev. Definicije teh storitev lahko spremenite v konfiguraciji. Na primer, za storitev application.application, ki je privzeto objekt Nette\Application\Application, lahko spremenimo razred:

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

Oznaka alteration je informativna in pove, da samo spreminjamo obstoječo storitev.

Dodamo lahko tudi nastavitev:

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

Pri ponovnem pisanju storitve bomo morda želeli odstraniti prvotne argumente, elemente nastavitev ali oznake, za kar je namenjen naslov reset:

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

Storitev, ki je bila dodana z razširitvijo, lahko tudi odstranimo iz vsebnika:

services:
	cache.journal: false
različica: 3.x