You are browsing the unmaintained documentation for old Nette 2.0. See documentation for current Nette.

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:
		class: Nette\Database\Connection(%dsn%, %user%, %password%)

#or in two lines
		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(Nette\DI\Container $container)
	{
		...
	}
}

Generates:

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

Setup

services:
	database:
		class: 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:
		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% )

Service definitions inheritance

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

Factories

Factories are defined in almost the same way as services:

factories:
	article:
		class: Article

Generates:

	function createArticle()
	{
		return new Article($this->database);
	}

Factory is called directly like $article = $container->createArticle();

Unlike services a factory can accept parameters:

factories:
	article:
		parameters: [id, title: null]
		class: Article(..., %id%)
		setup:
			- $title(%title%)

Generates:

	function createArticle($id, $title = NULL)
	{
		$service = new Article($this->database, $id);
		$service->title = $title;
		return $service;
	}

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:
		class: Nette\Caching\Storages\FileStorage(%tempDir%)

	tempCacheStorage:
		class: 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]