DI: Konfigurace

Přehled konfiguračních voleb pro Nette DI kontejner.

Nette DI kontejner se snadno ovládá pomocí konfiguračních souborů. Ty se obvykle zapisují ve formátu NEON. K editaci doporučujeme editory s podporou tohoto formátu.

 decorator: 	Dekorátor
di: DI kontejner
extensions: Instalace dalších DI rozšíření
includes: Vkládání souborů
parameters: Parametry
search: Automatická registrace služeb
services: Služby

Chcete-li zapsat řetězec začínající znakem @ nebo obsahující %, musíte znak escapovat zdvojením na @@ nebo %%.

Parametry

V konfiguraci můžete definovat parametry, které lze pak použít jako součást definic služeb. Čímž můžete zpřehlednit konfiguraci nebo sjednotit a vyčlenit hodnoty, které se budou měnit.

parameters:
	dsn: 'mysql:host=127.0.0.1;dbname=test'
	user: root
	password: secret

Na parametr dsn se odkážeme kdekoliv v konfiguraci zápisem %dsn%. Parametry lze používat i uvnitř řetězců jako '%wwwDir%/images'.

Parametry nemusí být jen řetězce nebo čísla, mohou také obsahovat pole:

parameters:
	mailer:
		host: smtp.example.com
		secure: ssl
		user: franta@gmail.com
	languages: [cs, en, de]

Na konkrétní klíč se odkážeme jako %mailer.user%.

Pokud potřebujete ve vašem kódu, například třídě, zjistit hodnotu jakékoliv parametru, tak jej do této třídy předejte. Například v konstruktoru. Neexistuje žádný globální objekt představující konfiguraci, kterého by se třídy dotazovaly na hodnoty parametrů. To by bylo porušením principu dependency injection.

Služby

Viz samostatná kapitola.

Decorator

Jak upravit hromadně všechny služby určitého typu? Třeba zavolat určitou metodu u všech presenterů, které dědí od konkrétního společného předka? Od toho je tu decorator.

decorator:
	# u všech služeb, co jsou instancí této třídy nebo rozhraní
	App\Presenters\BasePresenter:
		setup:
			- setProjectId(10)       # zavolej tuto metodu
			- $absoluteUrls = true   # a nastav proměnnou

Decorator se dá používat také pro nastavení tagů nebo zapnutí režimu inject.

decorator:
	InjectableInterface:
		tags: [mytag: 1]
		inject: true

DI

Technické nastavení DI kontejneru.

di:
	# zobrazit DIC v Tracy Bar?
	debugger: ...        # (bool) výchozí je true

	# typy parametrů, které nikdy neautowirovat
	excluded: ...        # (string[])

	# třída, od které dědí DI kontejner
	parentClass: ...     # (string) výchozí je Nette\DI\Container

Export metadat

Třída DI kontejneru obsahuje i spoustu metadat. Můžete ji zmenšit tím, že export metadat zredukujete.

di:
	export:
		# exportovat parametry?
		parameters: false   # (bool) výchozí je true

		# exportovat tagy a které?
		tags:               # (string[]|bool) výchozí jsou všechny
			- event.subscriber

		# exportovat data pro autowiring a které?
		types:              # (string[]|bool) výchozí jsou všechny
			- Nette\Database\Connection
			- Symfony\Component\Console\Application

Pokud nevyužíváte pole $container->parameters, můžete vypnout export parametrů. Dále můžete exportovat jen ty tagy, přes které získáváte služby metodou $container->findByTag(...). Pokud metodu nevoláte vůbec, můžete zcela vypnout export tagů pomocí false.

Výrazně můžete zredukovat metadata pro autowiring tím, že uvedete třídy, které používáte jako parametr metody $container->getByType(). A opět, pokud metodu nevoláte vůbec (resp. jen v bootstrapu pro získání Nette\Application\Application), můžete export úplně vypnout pomocí false.

Rozšíření

Registrace dalších DI rozšíření. Tímto způsobem přidáme např. DI rozšíření Dibi\Bridges\Nette\DibiExtension22 pod názvem dibi

extensions:
	dibi: Dibi\Bridges\Nette\DibiExtension22

Následně ho tedy konfigurujeme v sekci dibi:

dibi:
	host: localhost

Jako rozšíření lze přidat i třídu, která má parametry:

extensions:
	application: Nette\Bridges\ApplicationDI\ApplicationExtension(%debugMode%, %appDir%, %tempDir%/cache)

Vkládání souborů

Další konfigurační soubory můžeme vložit v sekci includes:

includes:
	- parameters.php
	- services.neon
	- presenters.neon

Název parameters.php není překlep, konfigurace může být zapsaná také v PHP souboru, který ji vrátí jako pole:

<?php
return [
	'database' => [
		'main' => [
			'dsn' => 'sqlite::memory:',
		],
	],
];

Pokud se v konfiguračních souborech objeví prvky se stejnými klíči, budou přepsány, nebo v případě polí sloučeny. Později vkládaný soubor má vyšší prioritu než předchozí. Soubor, ve kterém je sekce includes uvedena, má vyšší prioritu než v něm vkládané soubory.

Automatické přidávání služeb do DI kontejneru nesmírně zpříjemňuje práci. Nette automaticky přidává do kontejneru presentery, lze však snadno přidávat i jakékoliv jiné třídy.

Stačí uvést, ve kterých adresářích (a podadresářích) má třídy hledat:

search:
	# názvy sekcí si volíte sami
	formuláře:
		in: %appDir%/Forms

	model:
		in: %appDir%/Model

Obvykle ovšem nechceme přidávat úplně všechny třídy a rozhraní, proto je můžeme filtrovat:

search:
	formuláře:
		in: %appDir%/Forms

		# filtrování podle názvu souboru (string|string[])
		files:
			- *Factory.php

		# filtrování podle názvu třídy (string|string[])
		classes:
			- *Factory

Nebo můžeme vybírat třídy, které dědí či implementují alespoň jednu z uvedených tříd:

search:
	formuláře:
		extends:
			- App\*Form
		implements:
			- App\*FormInterface

Lze definovat i vylučující pravidla, tj. masky názvu třídy nebo dědičné předky, které pokud vyhovují, služba se do DI kontejneru nepřidá:

search:
	formuláře:
		exclude:
			classes: ...
			extends: ...
			implements: ...

Všem službám lze nastavit tagy:

search:
	formuláře:
		tags: ...

Slučování

Pokud se ve více konfiguračních souborech objeví prvky se stejnými klíči, budou přepsány, nebo v případě polí sloučeny. Později vkládaný soubor má vyšší prioritu než předchozí.

config1.neon config2.neon výsledek
items:
	- 1
	- 2
items:
	- 3
items:
	- 1
	- 2
	- 3

U polí lze zabránit slučování uvedením vykřičníku za názvem klíče:

config1.neon config2.neon výsledek
items:
	- 1
	- 2
items!:
	- 3
items:
	- 3