Nette Documentation Preview

syntax
Opredelitve storitev
********************

.[perex]
Konfiguracija je mesto, kjer vsebniku DI naročimo, kako naj sestavi posamezne storitve in kako naj jih poveže z drugimi odvisnostmi. Nette ponuja zelo jasen in eleganten način za doseganje tega cilja.

V razdelku `services` v konfiguracijski datoteki NEON opredelimo svoje storitve po meri in njihove konfiguracije. Oglejmo si preprost primer opredelitve storitve z imenom `database`, ki predstavlja primerek razreda `PDO`:

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

Rezultat te konfiguracije je naslednja tovarniška metoda v [vsebniku DI |container]:

```php
public function createServiceDatabase(): PDO
{
	return new PDO('sqlite::memory:');
}
```

Imena storitev nam omogočajo sklicevanje nanje v drugih delih konfiguracijske datoteke v obliki `@serviceName`. Če storitve ni treba poimenovati, lahko preprosto uporabimo točko:

```neon
services:
	- PDO('sqlite::memory:')
```

Za pridobitev storitve iz vsebnika DI lahko uporabimo metodo `getService()` z imenom storitve kot parametrom ali metodo `getByType()` s tipom storitve:

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


Ustvarjanje storitev .[#toc-service-creation]
=============================================

Najpogosteje ustvarimo storitev tako, da instanciramo določen razred. Na primer:

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

Če moramo konfiguracijo razširiti z dodatnimi ključi, lahko definicijo razširimo v več vrstic:

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

Ključ `create` ima vzdevek `factory`, obe različici sta v praksi pogosti. Vendar priporočamo uporabo ključa `create`.

Argumente konstruktorja ali metodo ustvarjanja lahko alternativno zapišete v ključu `arguments`:

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

Storitve niso nujno ustvarjene samo z enostavno instanciacijo razreda; lahko so tudi posledica klica statičnih metod ali metod drugih storitev:

```neon
services:
	database: DatabaseFactory::create()
	router: @routerFactory::create()
```

Upoštevajte, da zaradi enostavnosti namesto `->` uporabljamo `::`, glej [izrazna sredstva |#expression means]. Te tovarniške metode so ustvarjene:

```php
public function createServiceDatabase(): PDO
{
	return DatabaseFactory::create();
}

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

vsebnik DI mora poznati vrsto ustvarjene storitve. Če ustvarimo storitev z metodo, ki nima določene vrnitvene vrste, moramo to vrsto izrecno navesti v konfiguraciji:

```neon
services:
	database:
		create: DatabaseFactory::create()
		type: PDO
```


Argumenti .[#toc-arguments]
===========================

Argumente konstruktorjem in metodam posredujemo na zelo podoben način kot v običajnem jeziku PHP:

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

Za boljšo berljivost lahko argumente navedemo v ločenih vrsticah. V tej obliki je uporaba vejic neobvezna:

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

Argumente lahko tudi poimenujete, kar vam omogoča, da se ne ukvarjate z njihovim vrstnim redom:

```neon
services:
	database: PDO(
		username: root
		password: secret
		dsn: 'mysql:host=127.0.0.1;dbname=test'
	)
```

Če želite določene argumente izpustiti in uporabiti njihove privzete vrednosti ali vstaviti storitev prek [samodejnega napeljevanja |autowiring], uporabite podčrtaj:

```neon
services:
	foo: Foo(_, %appDir%)
```

Argumenti so lahko storitve, parametri in še veliko več, glejte [izrazna sredstva |#expression means].


Nastavitev .[#toc-setup]
========================

V razdelku `setup` opredelimo metode, ki jih je treba poklicati pri ustvarjanju storitve.

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

V jeziku PHP bi bilo to videti takole:

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

Poleg klicev metod lahko lastnostim posredujete tudi vrednosti. Podprto je tudi dodajanje elementa v polje, vendar ga morate zapreti v narekovaje, da ne pride do kolizije s sintakso NEON:

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

V jeziku PHP bi to pomenilo:

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

V nastavitvi lahko kličete tudi statične metode ali metode drugih storitev. Če morate kot argument posredovati trenutno storitev, uporabite `@self`:

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

Upoštevajte, da zaradi enostavnosti namesto `->` uporabimo `::`, glejte [izrazna sredstva |#expression means]. To ustvari naslednjo tovarniško metodo:

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


Sredstva za izražanje .[#toc-expression-means]
==============================================

Nette DI nam zagotavlja izjemno bogate izrazne možnosti, s katerimi lahko izrazimo skoraj vse. V konfiguracijskih datotekah lahko uporabljamo [parametre |configuration#parameters]:

```neon
# parameter
%wwwDir%

# vrednost pod ključem parametra
%mailer.user%

# parameter v nizu
'%wwwDir%/images'
```

Prav tako lahko ustvarjamo predmete, kličemo metode in funkcije:

```neon
# ustvariti predmet
DateTime()

# klic statične metode
Collator::create(%locale%)

# klic funkcije PHP
::getenv(DB_USER)
```

Na storitve se lahko sklicujemo po imenu ali vrsti:

```neon
# storitev po imenu
@database

# storitev po vrsti
@Nette\Database\Connection
```

Uporabite sintakso prvega razreda za klicanje: .{data-version:3.2.0}

```neon
# creating a callback, equivalent to [@user, logout]
@user::logout(...)
```

Uporabite konstante:

```neon
# razred stalnica
FilesystemIterator::SKIP_DOTS

# globalna konstanta, pridobljena s funkcijo PHP constant()
::constant(PHP_VERSION)
```

Tako kot v PHP lahko klice metod verižite. Zaradi preprostosti namesto `->` uporabimo `::`:

```neon
DateTime()::format('Y-m-d')
# PHP: (new DateTime())->format('Y-m-d')

@http.request::getUrl()::getHost()
# PHP: $this->getService('http.request')->getUrl()->getHost()
```

Te izraze lahko pri [ustvarjanju storitev |#Service Creation] uporabite kjer koli, v [argumentih |#Arguments], v [nastavitvenem |#setup] delu ali [parametrih |configuration#parameters]:

```neon
parameters:
	ipAddress: @http.request::getRemoteAddress()

services:
	database:
		create: DatabaseFactory::create( @anotherService::getDsn() )
		setup:
			- initialize( ::getenv('DB_USER') )
```


Posebne funkcije .[#toc-special-functions]
------------------------------------------

V konfiguracijskih datotekah lahko uporabite te posebne funkcije:

- `not()` za zanikanje vrednosti
- `bool()`, `int()`, `float()`, `string()` za brezizgubno ulivanje tipov
- `typed()` za ustvarjanje polja vseh storitev določenega tipa
- `tagged()` za ustvarjanje polja vseh storitev z določeno oznako

```neon
services:
	- Foo(
		id: int(::getenv('ProjectId'))
		productionMode: not(%debugMode%)
	)
```

V primerjavi z običajnim tipiziranjem v PHP, kot je `(int)`, bo brezizgubno tipiziranje vrglo izjemo za neštevilčne vrednosti.

Funkcija `typed()` ustvari polje vseh storitev določene vrste (razreda ali vmesnika). Izključuje storitve z izklopljenim samodejnim vgrajevanjem. Določite lahko več vrst, ki jih ločite z vejicami.

```neon
services:
	- BarsDependent( typed(Bar) )
```

Kot argument lahko samodejno posredujete tudi polje storitev določene vrste z uporabo [samodejnega napeljevanja |autowiring#Collection of Services].

Funkcija `tagged()` ustvari polje vseh storitev z določeno oznako. Navedete lahko več oznak, ki jih ločite z vejicami.

```neon
services:
	- LoggersDependent( tagged(logger) )
```


Avtomatska napeljava .[#toc-autowiring]
=======================================

Ključ `autowired` omogoča spreminjanje obnašanja samodejnega ožičenja za določeno storitev. Za več podrobnosti glejte [poglavje o samodejnem ožičenju |autowiring].

```neon
services:
	foo:
		create: Foo
		autowired: false     # storitev foo je izključena iz samodejnega ožičenja
```


Oznake .[#toc-tags]
===================

Oznake se uporabljajo za dodajanje dodatnih informacij storitvam. Storitvi lahko dodelite eno ali več oznak:

```neon
services:
	foo:
		create: Foo
		tags:
			- cached
```

Oznake lahko nosijo tudi vrednosti:

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

Če želite priklicati vse storitve z določenimi oznakami, lahko uporabite funkcijo `tagged()`:

```neon
services:
	- LoggersDependent( tagged(logger) )
```

V vsebniku DI lahko z metodo `findByTag()` pridobite imena vseh storitev z določeno oznako:

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


Način vbrizgavanja .[#toc-inject-mode]
======================================

Uporaba oznake `inject: true` aktivira posredovanje odvisnosti prek javnih spremenljivk z opombo [inject |best-practices:inject-method-attribute#Inject Attributes] in metodami [inject*( |best-practices:inject-method-attribute#inject Methods] ).

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

Privzeto je funkcija `inject` aktivirana samo za predstavnike.


Spremembe storitev .[#toc-service-modifications]
================================================

Vsebnik DI vsebuje številne storitve, ki so dodane z vgrajenimi ali [uporabniškimi razširitvami |#extensions]. Definicije teh storitev lahko spreminjate neposredno v konfiguraciji. Tako lahko na primer spremenite razred storitve `application.application`, ki je običajno `Nette\Application\Application`, v drug razred:

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

Oznaka `alteration` je informativna in pomeni, da zgolj spreminjamo obstoječo storitev.

Nastavitev lahko tudi dopolnimo:

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

Pri prepisovanju storitve boste morda želeli odstraniti prvotne argumente, nastavitvene elemente ali oznake, pri čemer vam pride prav `reset`:

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

Če želite odstraniti storitev, ki jo je dodala razširitev, lahko to storite na naslednji način:

```neon
services:
	cache.journal: false
```

Opredelitve storitev

Konfiguracija je mesto, kjer vsebniku DI naročimo, kako naj sestavi posamezne storitve in kako naj jih poveže z drugimi odvisnostmi. Nette ponuja zelo jasen in eleganten način za doseganje tega cilja.

V razdelku services v konfiguracijski datoteki NEON opredelimo svoje storitve po meri in njihove konfiguracije. Oglejmo si preprost primer opredelitve storitve z imenom database, ki predstavlja primerek razreda PDO:

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

Rezultat te konfiguracije je naslednja tovarniška metoda v vsebniku DI:

public function createServiceDatabase(): PDO
{
	return new PDO('sqlite::memory:');
}

Imena storitev nam omogočajo sklicevanje nanje v drugih delih konfiguracijske datoteke v obliki @serviceName. Če storitve ni treba poimenovati, lahko preprosto uporabimo točko:

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

Za pridobitev storitve iz vsebnika DI lahko uporabimo metodo getService() z imenom storitve kot parametrom ali metodo getByType() s tipom storitve:

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

Ustvarjanje storitev

Najpogosteje ustvarimo storitev tako, da instanciramo določen razred. Na primer:

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

Če moramo konfiguracijo razširiti z dodatnimi ključi, lahko definicijo razširimo v več vrstic:

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

Ključ create ima vzdevek factory, obe različici sta v praksi pogosti. Vendar priporočamo uporabo ključa create.

Argumente konstruktorja ali metodo ustvarjanja lahko alternativno zapišete v ključu arguments:

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

Storitve niso nujno ustvarjene samo z enostavno instanciacijo razreda; lahko so tudi posledica klica statičnih metod ali metod drugih storitev:

services:
	database: DatabaseFactory::create()
	router: @routerFactory::create()

Upoštevajte, da zaradi enostavnosti namesto -> uporabljamo ::, glej izrazna sredstva. Te tovarniške metode so ustvarjene:

public function createServiceDatabase(): PDO
{
	return DatabaseFactory::create();
}

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

vsebnik DI mora poznati vrsto ustvarjene storitve. Če ustvarimo storitev z metodo, ki nima določene vrnitvene vrste, moramo to vrsto izrecno navesti v konfiguraciji:

services:
	database:
		create: DatabaseFactory::create()
		type: PDO

Argumenti

Argumente konstruktorjem in metodam posredujemo na zelo podoben način kot v običajnem jeziku PHP:

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

Za boljšo berljivost lahko argumente navedemo v ločenih vrsticah. V tej obliki je uporaba vejic neobvezna:

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

Argumente lahko tudi poimenujete, kar vam omogoča, da se ne ukvarjate z njihovim vrstnim redom:

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

Če želite določene argumente izpustiti in uporabiti njihove privzete vrednosti ali vstaviti storitev prek samodejnega napeljevanja, uporabite podčrtaj:

services:
	foo: Foo(_, %appDir%)

Argumenti so lahko storitve, parametri in še veliko več, glejte izrazna sredstva.

Nastavitev

V razdelku setup opredelimo metode, ki jih je treba poklicati pri ustvarjanju storitve.

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

V jeziku PHP bi bilo to videti takole:

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

Poleg klicev metod lahko lastnostim posredujete tudi vrednosti. Podprto je tudi dodajanje elementa v polje, vendar ga morate zapreti v narekovaje, da ne pride do kolizije s sintakso NEON:

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

V jeziku PHP bi to pomenilo:

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

V nastavitvi lahko kličete tudi statične metode ali metode drugih storitev. Če morate kot argument posredovati trenutno storitev, uporabite @self:

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

Upoštevajte, da zaradi enostavnosti namesto -> uporabimo ::, glejte izrazna sredstva. To ustvari naslednjo tovarniško metodo:

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

Sredstva za izražanje

Nette DI nam zagotavlja izjemno bogate izrazne možnosti, s katerimi lahko izrazimo skoraj vse. V konfiguracijskih datotekah lahko uporabljamo parametre:

# parameter
%wwwDir%

# vrednost pod ključem parametra
%mailer.user%

# parameter v nizu
'%wwwDir%/images'

Prav tako lahko ustvarjamo predmete, kličemo metode in funkcije:

# ustvariti predmet
DateTime()

# klic statične metode
Collator::create(%locale%)

# klic funkcije PHP
::getenv(DB_USER)

Na storitve se lahko sklicujemo po imenu ali vrsti:

# storitev po imenu
@database

# storitev po vrsti
@Nette\Database\Connection

Uporabite sintakso prvega razreda za klicanje:

# creating a callback, equivalent to [@user, logout]
@user::logout(...)

Uporabite konstante:

# razred stalnica
FilesystemIterator::SKIP_DOTS

# globalna konstanta, pridobljena s funkcijo PHP constant()
::constant(PHP_VERSION)

Tako kot v PHP lahko klice metod verižite. Zaradi preprostosti namesto -> uporabimo :::

DateTime()::format('Y-m-d')
# PHP: (new DateTime())->format('Y-m-d')

@http.request::getUrl()::getHost()
# PHP: $this->getService('http.request')->getUrl()->getHost()

Te izraze lahko pri ustvarjanju storitev uporabite kjer koli, v argumentih, v nastavitvenem delu ali parametrih:

parameters:
	ipAddress: @http.request::getRemoteAddress()

services:
	database:
		create: DatabaseFactory::create( @anotherService::getDsn() )
		setup:
			- initialize( ::getenv('DB_USER') )

Posebne funkcije

V konfiguracijskih datotekah lahko uporabite te posebne funkcije:

  • not() za zanikanje vrednosti
  • bool(), int(), float(), string() za brezizgubno ulivanje tipov
  • typed() za ustvarjanje polja vseh storitev določenega tipa
  • tagged() za ustvarjanje polja vseh storitev z določeno oznako
services:
	- Foo(
		id: int(::getenv('ProjectId'))
		productionMode: not(%debugMode%)
	)

V primerjavi z običajnim tipiziranjem v PHP, kot je (int), bo brezizgubno tipiziranje vrglo izjemo za neštevilčne vrednosti.

Funkcija typed() ustvari polje vseh storitev določene vrste (razreda ali vmesnika). Izključuje storitve z izklopljenim samodejnim vgrajevanjem. Določite lahko več vrst, ki jih ločite z vejicami.

services:
	- BarsDependent( typed(Bar) )

Kot argument lahko samodejno posredujete tudi polje storitev določene vrste z uporabo samodejnega napeljevanja.

Funkcija tagged() ustvari polje vseh storitev z določeno oznako. Navedete lahko več oznak, ki jih ločite z vejicami.

services:
	- LoggersDependent( tagged(logger) )

Avtomatska napeljava

Ključ autowired omogoča spreminjanje obnašanja samodejnega ožičenja za določeno storitev. Za več podrobnosti glejte poglavje o samodejnem ožičenju.

services:
	foo:
		create: Foo
		autowired: false     # storitev foo je izključena iz samodejnega ožičenja

Oznake

Oznake se uporabljajo za dodajanje dodatnih informacij storitvam. Storitvi lahko dodelite eno ali več oznak:

services:
	foo:
		create: Foo
		tags:
			- cached

Oznake lahko nosijo tudi vrednosti:

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

Če želite priklicati vse storitve z določenimi oznakami, lahko uporabite funkcijo tagged():

services:
	- LoggersDependent( tagged(logger) )

V vsebniku DI lahko z metodo findByTag() pridobite imena vseh storitev z določeno oznako:

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

Način vbrizgavanja

Uporaba oznake inject: true 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.

Spremembe storitev

Vsebnik DI vsebuje številne storitve, ki so dodane z vgrajenimi ali uporabniškimi razširitvami. Definicije teh storitev lahko spreminjate neposredno v konfiguraciji. Tako lahko na primer spremenite razred storitve application.application, ki je običajno Nette\Application\Application, v drug razred:

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

Oznaka alteration je informativna in pomeni, da zgolj spreminjamo obstoječo storitev.

Nastavitev lahko tudi dopolnimo:

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

Pri prepisovanju storitve boste morda želeli odstraniti prvotne argumente, nastavitvene elemente ali oznake, pri čemer vam pride prav reset:

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

Če želite odstraniti storitev, ki jo je dodala razširitev, lahko to storite na naslednji način:

services:
	cache.journal: false