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: Nette\Database\Connection(%dsn%, %user%, %password%)
# nebo ve dvou řádcích:
database:
factory: Nette\Database\Connection(%dsn%, %user%, %password%)
# nebo ve třech řádcích :-)
database:
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:
factory: 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:
factory: 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% )
Anonymní služby
V konfiguračním souboru mohou být i služby, na které již není odkazováno v žádném dalším konfiguračním souboru. Takové služby není potřeba pojmenovávat. Pro anonymní služby použijte následující syntax:
services:
- Simple\Service
-
factory: Complex\Service
setup:
- setLang(%lang%)
Pokud však budete chtít později odkázat na anonymní službu, budete muset uvést úplný název třídy (rozhraní).
services:
router: @App\RouterFactory::createRouter
Také je potřeba mít na paměti, že z povahy anonymních služeb nelze mít registrovaných více instancí stejného typu, jelikož by nebylo možné je rozlišit.
Dědičnost služeb
services:
dev_database < database
setup:
- Diagnostics\ConnectionPanel::initialize
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:
factory: Nette\Caching\Storages\FileStorage(%tempDir%)
tempCacheStorage:
factory: 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]