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 boolint(%arg%)
veszteségmentes átváltás int-refloat(%arg%)
lossless cast to floatstring(%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