Nette DI Container
Nette DI Container is one of the most interesting part of framework. It can generate compiled DI containers that are extremely fast and amazingly easy to configure.
Nette DI is a library that provides tools for generating and also automatically updating container classes. We instruct it (usually) using configuration files. The container we manually created in previous section would be written in the configuration NEON format as follows:
parameters:
db:
dsn: 'mysql:'
user: root
password: '***'
services:
- Nette\Database\Connection(%db.dsn%, %db.user%, %db.password%)
- ArticleFactory
- UserController
The notation is really brief.
All dependencies declared in constructors of ArticleFactory
and UserController
are automatically
detected and passed by Nette DI thanks to the so-called autowiring. So you can concentrate on
development.
If you want to pass dependencies using a setter, we can add a setup section to the service definition.
Nette DI will actually generate the PHP code for the container. It is therefore extremely fast, the programmer knows exactly what he is doing and can even step it. A container can be tens of thousands of lines long for large applications, and maintaining something like this manually would probably not even be possible anymore.
Nette DI can also generate factory code based on the interface. So instead of a class
ArticleFactory
, you would just need to create an interface:
interface ArticleFactory
{
function create(): Article;
}
You can find the full example on GitHub.
Using It Without a Framework
Utilization of Nette DI in an application is very easy. First we install it with Composer (because downloading zip files is so outdated):
composer require nette/di
We save the above configuration in a file config.neon
and create a container using class
Nette\DI\ContainerLoader
:
$loader = new Nette\DI\ContainerLoader(__DIR__ . '/temp');
$class = $loader->load(function($compiler) {
$compiler->loadConfig(__DIR__ . '/config.neon');
});
$container = new $class;
and then let it create an object for example Nette\Database\Connection
:
$database = $container->getByType(Nette\Database\Connection::class);
$database->query('...');
But back to ContainerLoader
for a moment. That notation is subject to one thing: speed. The container is generated
once, its code is written to the cache (directory __DIR__ . '/temp'
), and on subsequent requests it is only retrieved
from there. Therefore, the configuration retrieval is placed in the closure in method $loader->load()
.
During development, it is useful to enable auto-refresh mode, where the container is automatically re-generated if any class or
configuration file is changed. Just provide true
as the second argument in the constructor
ContainerLoader
.
As you can see, the use of Nette DI is definitely not limited to applications written in Nette, you can deploy it anywhere with just 3 lines of code.
Using It with the Nette Framework
If you are developing applications in Nette, the configuration and creation of the container is handled by Bootstrap.