Nette Documentation Preview

syntax
Generated Factories
*******************

.[perex]
Nette DI can automatically generate factory code based on the interface, which saves you from writing code.

A factory is a class that creates and configures objects. It therefore passes their dependencies to them as well. We showed what such a factory looks like in [introduction|introduction#factory]:

```php
class ArticleFactory
{
	private Nette\Database\Connection $db;

	public function __construct(Nette\Database\Connection $db)
	{
		$this->db = $db;
	}

	public function create(): Article
	{
		return new Article($this->db);
	}
}
```

Nette DI can generate factory code automatically. All you have to do is create an interface and Nette DI will generate an implementation. The interface must have exactly one method named `create` and declare a return type:

```php
interface ArticleFactory
{
	function create(): Article;
}
```

So the factory `ArticleFactory` has a method `create` that creates objects `Article`. Class `Article` might look like the following, for example:

```php
class Article
{
	private $db;

	public function __construct(Nette\Database\Connection $db)
	{
		$this->db = $db;
	}
}
```

Add the factory to the configuration file:

```neon
services:
	- ArticleFactory
```

Nette DI will generate the corresponding factory implementation.

Thus, in the code that uses the factory, we request the object by interface and Nette DI uses the generated implementation:

```php
class UserController
{
	private $articleFactory;

	public function __construct(ArticleFactory $articleFactory)
	{
		$this->articleFactory = $articleFactory;
	}

	public function foo()
	{
		// let the factory create an object
		$article = $this->articleFactory->create();
	}
}
```


Parameterized Factory
=====================

The factory method `create` can accept parameters which it then passes to the constructor. For example, let's add an article author ID to the class `Article`:

```php
class Article
{
	private $db;
	private $authorId;

	public function __construct(Nette\Database\Connection $db, int $authorId)
	{
		$this->db = $db;
		$this->authorId = $authorId;
	}
}
```

We will also add the parameter to the factory:

```php
interface ArticleFactory
{
	function create(int $authorId): Article;
}
```

Because the parameter in the constructor and the parameter in the factory have the same name, Nette DI will pass them automatically.


Advanced Definition
===================

The definition can also be written in multi-line form using the key `implement`:

```neon
services:
	articleFactory:
		implement: ArticleFactory
```

When writing in this longer way, it is possible to provide additional arguments for the constructor in the key `arguments` and additional configuration using `setup`, just as for normal services.

Example: if the method `create()` did not accept the parameter `$authorId`, we could specify a fixed value in the configuration that would be passed to the constructor `Article`:

```neon
services:
	articleFactory:
		implement: ArticleFactory
		arguments:
			authorId: 123
```

Or, conversely, if `create()` did accept the parameter `$authorId` but it was not part of the constructor and was passed by method `Article::setAuthorId()`, we would refer to it in section `setup`:

```neon
services:
	articleFactory:
		implement: ArticleFactory
		setup:
			- setAuthorId($authorId)
```


Component Factory
=================

How to create complex components with many dependencies without "messing up" the presenters that will use them? Thanks to the clever features of the DI container in Nette, as with using classic services, we can leave most of the work to the framework.

Let's take as an example a component that has dependencies on several services:

```php
class MyControl extends Nette\Application\UI\Control
{
	public function __construct(
		EmailValidator $emailValidator,
		Registrator $registrator,
		Mailer $mailer
	) {
		//
	}
}
```

If we were writing a classic service, there would be nothing to worry about. The DI container would invisibly take care of passing all the dependencies. But we usually handle components by creating a new instance of them directly in the presenter in the factory methods `createComponent…()`.
And passing all our dependencies to the presenter to then pass them to the component is a tiresome and cumbersome solution. It means introducing private variables in the presenter that find no use outside of a single method. And the thought of the amount of code you have to write...

```php
class MyPresenter extends Nette\Application\UI\Presenter
{
	private $emailValidator;
	private $registrator;
	private $mailer;

	public function __construct(
		EmailValidator $emailValidator,
		Registrator $registrator,
		Mailer $mailer
	) {
		$this->emailValidator = $emailValidator;
		$this->registrator = $registrator;
		$this->mailer = $mailer;
	}

	protected function createComponentMyControl(): MyControl
	{
		$control = new MyControl(
			$this->emailValidator,
			$this->registrator,
			$this->mailer
		);
		return $control;
	}
}
```

The logical question is why don't we just register the component as a classic service, pass it to the presenter and then return it in the `createComponent…()` method? However, this approach is extremely inappropriate because we normally want to create the component multiple times.

The architecturally correct solution, which does not pollute the presenter with unnecessary dependencies, is to write a factory for the component. Again, we can have it generated based on the interface. For example, our interface for a component might look like this:

```php
interface MyControlFactory
{
	public function create(): MyControl;
}
```

We register the factory in the configuration file:

```neon
services:
	- MyControlFactory
```

In the presenter, it will then be enough to get the factory and call the method `create`:

```php
class MyPresenter extends Nette\Application\UI\Presenter
{
	private $myControlFactory;

	public function __construct(MyControlFactory $myControlFactory)
	{
		$this->myControlFactory = $myControlFactory;
	}

	protected function createComponentMyControl(): MyControl
	{
		$control = $this->myControlFactory->create();
		return $control;
	}
}
```

The created component will be automatically passed its dependencies by the constructor.

{{composer: nette/di}}
/--comment
TODO: extensive update
\--

Generated Factories

Nette DI can automatically generate factory code based on the interface, which saves you from writing code.

A factory is a class that creates and configures objects. It therefore passes their dependencies to them as well. We showed what such a factory looks like in introduction:

class ArticleFactory
{
	private Nette\Database\Connection $db;

	public function __construct(Nette\Database\Connection $db)
	{
		$this->db = $db;
	}

	public function create(): Article
	{
		return new Article($this->db);
	}
}

Nette DI can generate factory code automatically. All you have to do is create an interface and Nette DI will generate an implementation. The interface must have exactly one method named create and declare a return type:

interface ArticleFactory
{
	function create(): Article;
}

So the factory ArticleFactory has a method create that creates objects Article. Class Article might look like the following, for example:

class Article
{
	private $db;

	public function __construct(Nette\Database\Connection $db)
	{
		$this->db = $db;
	}
}

Add the factory to the configuration file:

services:
	- ArticleFactory

Nette DI will generate the corresponding factory implementation.

Thus, in the code that uses the factory, we request the object by interface and Nette DI uses the generated implementation:

class UserController
{
	private $articleFactory;

	public function __construct(ArticleFactory $articleFactory)
	{
		$this->articleFactory = $articleFactory;
	}

	public function foo()
	{
		// let the factory create an object
		$article = $this->articleFactory->create();
	}
}

Parameterized Factory

The factory method create can accept parameters which it then passes to the constructor. For example, let's add an article author ID to the class Article:

class Article
{
	private $db;
	private $authorId;

	public function __construct(Nette\Database\Connection $db, int $authorId)
	{
		$this->db = $db;
		$this->authorId = $authorId;
	}
}

We will also add the parameter to the factory:

interface ArticleFactory
{
	function create(int $authorId): Article;
}

Because the parameter in the constructor and the parameter in the factory have the same name, Nette DI will pass them automatically.

Advanced Definition

The definition can also be written in multi-line form using the key implement:

services:
	articleFactory:
		implement: ArticleFactory

When writing in this longer way, it is possible to provide additional arguments for the constructor in the key arguments and additional configuration using setup, just as for normal services.

Example: if the method create() did not accept the parameter $authorId, we could specify a fixed value in the configuration that would be passed to the constructor Article:

services:
	articleFactory:
		implement: ArticleFactory
		arguments:
			authorId: 123

Or, conversely, if create() did accept the parameter $authorId but it was not part of the constructor and was passed by method Article::setAuthorId(), we would refer to it in section setup:

services:
	articleFactory:
		implement: ArticleFactory
		setup:
			- setAuthorId($authorId)

Component Factory

How to create complex components with many dependencies without „messing up“ the presenters that will use them? Thanks to the clever features of the DI container in Nette, as with using classic services, we can leave most of the work to the framework.

Let's take as an example a component that has dependencies on several services:

class MyControl extends Nette\Application\UI\Control
{
	public function __construct(
		EmailValidator $emailValidator,
		Registrator $registrator,
		Mailer $mailer
	) {
		//
	}
}

If we were writing a classic service, there would be nothing to worry about. The DI container would invisibly take care of passing all the dependencies. But we usually handle components by creating a new instance of them directly in the presenter in the factory methods createComponent…(). And passing all our dependencies to the presenter to then pass them to the component is a tiresome and cumbersome solution. It means introducing private variables in the presenter that find no use outside of a single method. And the thought of the amount of code you have to write…

class MyPresenter extends Nette\Application\UI\Presenter
{
	private $emailValidator;
	private $registrator;
	private $mailer;

	public function __construct(
		EmailValidator $emailValidator,
		Registrator $registrator,
		Mailer $mailer
	) {
		$this->emailValidator = $emailValidator;
		$this->registrator = $registrator;
		$this->mailer = $mailer;
	}

	protected function createComponentMyControl(): MyControl
	{
		$control = new MyControl(
			$this->emailValidator,
			$this->registrator,
			$this->mailer
		);
		return $control;
	}
}

The logical question is why don't we just register the component as a classic service, pass it to the presenter and then return it in the createComponent…() method? However, this approach is extremely inappropriate because we normally want to create the component multiple times.

The architecturally correct solution, which does not pollute the presenter with unnecessary dependencies, is to write a factory for the component. Again, we can have it generated based on the interface. For example, our interface for a component might look like this:

interface MyControlFactory
{
	public function create(): MyControl;
}

We register the factory in the configuration file:

services:
	- MyControlFactory

In the presenter, it will then be enough to get the factory and call the method create:

class MyPresenter extends Nette\Application\UI\Presenter
{
	private $myControlFactory;

	public function __construct(MyControlFactory $myControlFactory)
	{
		$this->myControlFactory = $myControlFactory;
	}

	protected function createComponentMyControl(): MyControl
	{
		$control = $this->myControlFactory->create();
		return $control;
	}
}

The created component will be automatically passed its dependencies by the constructor.