Nette Documentation Preview

DI: Services Configuration

Dependency injection (DI) container is easily configured using NEON files.

The configuration is usually written in NEON format. Have fun trying out the syntax at https://ne-on.org.

services:
	database: Nette\Database\Connection(%dsn%, %user%, %password%)

# or multi-lines
	database:
		factory: Nette\Database\Connection(%dsn%, %user%, %password%)

# or more multi-lines :-)
	database:
		class: Nette\Database\Connection
		arguments: [%dsn%, %user%, %password%]

Generates:

function createServiceDatabase()
{
	return new Nette\Database\Connection(
		$this->parameters['dsn'],
		$this->parameters['user'],
		$this->parameters['password']
	);
}

Service definition:

services:
	database:
		class: Nette\Database\Connection
		factory: DbFactory::createConnection

DbFactory::createConnection:

class DbFactory
{
	static function createConnection()
	{
		...
	}
}

Generates:

function createServiceDatabase()
{
	return DbFactory::createConnection($this);
}

Setup

services:
	database:
		factory: Nette\Database\Connection(%dsn%, %user%, %password%)
		setup:
			- setCacheStorage(@cacheStorage)

Generates:

function createServiceDatabase()
{
	$service = new Nette\Database\Connection(...);
	$service->setCacheStorage($this->cacheStorage);
	return $service;
}

Autowiring feature adds dependencies automatically, so they don't even have to be mentioned:

setup:
	- setCacheStorage

In case the cacheStorage service does not exist, it is possible to use a result of a call as a parameter:

setup:
	- setCacheStorage( Factory::createStorage() )

# or a method of other service:
	- setCacheStorage( @factory::createStorage() )

Alternatively a newly created class instance:

setup:
	- setCacheStorage( Nette\Caching\Storages\FileStorage(%tempDir%) )

# generates: $service->setCacheStorage(new Nette\Caching\Storages\FileStorage(...));

You can also set a value of a property:

substitutions

setup:
	- $substitutions( [db: test] )

# generates: $service->substitutions = array('db' => 'test');

Full example:

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% )

Anonymous services

Time after time there are services that are in fact not referenced anywhere else in config files. Naming these services in this case is not necessary. To define an anonymous service, use the following syntax:

services:
	- Simple\Service

	-
		factory: Complex\Service
		setup:
			- setLang(%lang%)

To refer to such anonymous service you will need to use the fully qualified class name instead.

services:
	router: @App\RouterFactory::createRouter

Keep in mind that from a nature of anonymous services, it is not possible to register more than one of the same type, because it would lead to an ambiguity.

Service definitions inheritance

services:
	dev_database < database
		setup:
			- Diagnostics\ConnectionPanel::initialize

Auto-wiring

Auto-wiring feature can automatically pass dependencies into constructor and methods of the service. It uses typehinting and @return annotations. There can be only one service matching the type in the container, otherwise an exception is thrown.

To define more than one service of the same type we need to exclude them from auto-wiring:

services:
	cacheStorage:
		factory: Nette\Caching\Storages\FileStorage(%tempDir%)

	tempCacheStorage:
		factory: Nette\Caching\Storages\DevNullStorage
		autowired: no

When modifying the Nette Framework's core services we need to make sure the container is aware of the classes we want to use. That means using fully qualified class names in @return annotations or set the FQ class name with class entry.

Multiple configuration files

Use includes section to add more configuration files.

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

Configuration merging process assigns the highest priority to the file containing includes section and the lowest priority to the first included file. To prevent merging of a certain array use exclamation mark right after the name of the array:

argument!: [1, 2, 3]