DI: konfigurace služeb
Samotná konfigurace se obykle zapisuje v NEON souboru. Se syntaxí se můžete seznámit na stránce https://ne-on.org. V souboru můžeme nastavit
Konfigurační soubor je místem, kam umísťujeme definice vlastních služeb. Slouží k tomu sekce services
.
Například tato definice služby:
services:
database:
class: Nette\Database\Connection(%dsn%, %user%, %password%)
#nebo ve dvou řádcích:
class: Nette\Database\Connection
arguments: [%dsn%, %user%, %password%]
Vygeneruje:
function createServiceDatabase()
{
return new Nette\Database\Connection(
$this->parameters['dsn'],
$this->parameters['user'],
$this->parameters['password']
);
}
Definice služby:
services:
database:
class: Nette\Database\Connection
factory: DbFactory::createConnection
DbFactory::createConnection
:
class DbFactory
{
static function createConnection(Nette\DI\Container $container)
{
...
}
}
Vygeneruje:
function createServiceDatabase()
{
return DbFactory::createConnection($this);
}
Setup
services:
database:
class: Nette\Database\Connection(%dsn%, %user%, %password%)
setup:
- setCacheStorage(@cacheStorage)
Vygeneruje:
function createServiceDatabase()
{
$service = new Nette\Database\Connection(...);
$service->setCacheStorage($this->cacheStorage);
return $service;
}
Autowiring umí odkazy na jiné služby doplnit automaticky, takže lze parametry úplně vynechat:
setup:
- setCacheStorage
Pokud služba cacheStorage
neexistuje, můžeme jako parametr uvést výsledek volání funkce:
setup:
- setCacheStorage( Factory::createStorage() )
# nebo metody jiné služby:
- setCacheStorage( @factory::createStorage() )
Případně nově vytvořenou třídu:
setup:
- setCacheStorage( Nette\Caching\Storages\FileStorage(%tempDir%) )
# vygeneruje: $service->setCacheStorage(new Nette\Caching\Storages\FileStorage(...));
Lze nastavovat i hodnoty proměnných:
substitutions
setup:
- $substitutions( [db: test] )
# vygeneruje: $service->substitutions = array('db' => 'test');
Kompletní příklad:
parameters:
database:
driver: mysql
host: localhost
dbname: test
user: jim
password: beam
substitutions:
db: test
services:
database:
class: Nette\Database\Connection(
'%database.driver%:host=%database.host%;dbname=%database.dbname%',
%database.user%, %database.password%, null,
Nette\Database\Reflection\DiscoveredReflection()
)
setup:
- setCacheStorage
- $substitutions( %database.substitutions% )
Dědičnost služeb
services:
dev_database < database
setup:
- Diagnostics\ConnectionPanel::initialize
Továrny
Továrny se definují takřka stejně jako služby:
factories:
article:
class: Article
Vygeneruje:
function createArticle()
{
return new Article($this->database);
}
Továrnu pak voláme přímo $article = $container->createArticle();
Továrnám lze na rozdíl od služeb předávat parametry:
factories:
article:
parameters: [id, title: null]
class: Article(..., %id%)
setup:
- $title(%title%)
Vygeneruje:
function createArticle($id, $title = NULL)
{
$service = new Article($this->database, $id);
$service->title = $title;
return $service;
}
Auto-wiring
Auto-wiring umí automaticky předávat do konstruktoru a dalších metod požadované služby. Řídí se podle type hintů a
anotací @return
. Služba odpovídající hledané třídě musí být v kontejneru právě jedna, jinak se vyhodí
výjimka.
Pokud potřebujeme definovat více služeb stejného typu, můžeme je z auto-wiringu vyřadit:
services:
cacheStorage:
class: Nette\Caching\Storages\FileStorage(%tempDir%)
tempCacheStorage:
class: Nette\Caching\Storages\DevNullStorage
autowired: no
Pokud upravujeme základní služby Nette Frameworku, nesmíme se zapomenout ujistit, že kontejner zná třídy naší
implementace. Pokud tedy nastavujeme vlastní factory
pro službu, tak to znamená mít správně absolutní název
třídy v annotaci @return
, nebo nastavovat vždy i třídu do class
.
Více konfiguračních souborů
Vkládané soubory se uvádějí v sekci includes
.
includes:
- parameters.php
- services.neon
- presenters.neon
Konfigurace se slučují tak, že nejvyšší prioritu má soubor obsahující sekci includes
a nejnižší první
vkládaný soubor. Slučování polí lze zabránit uvedením vykřičníku za název pole:
argument!: [1, 2, 3]