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 vrednostibool()
,int()
,float()
,string()
za brezizgubno ulivanje tipovtyped()
za ustvarjanje polja vseh storitev določenega tipatagged()
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