Nette DI Container
Nette DI is one of the most interesting Nette libraries. It can generate and automatically update compiled DI containers that are extremely fast and amazingly easy to configure.
The services to be created by a DI container are usually defined using configuration files in NEON format. The container we manually created in previous section would be written 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 the constructors of the ArticleFactory
and UserController
classes are
found and passed by Nette DI itself thanks to the so-called autowiring, so there is no need to specify anything in the
configuration file. So even if the parameters change, you don't need to change anything in the configuration. Nette will
automatically regenerate the container. You can concentrate there purely on application development.
If you want to pass dependencies using setters, use the setup section to do so.
Nette DI will directly generate the PHP code for the container. The result is thus a .php
file that you can open
and study. This allows you to see exactly how the container works. You can also debug it in the IDE and step through it. And most
importantly: the generated PHP is extremely fast.
Nette DI can also generate factory code based on the
supplied interface. Therefore, instead of the ArticleFactory
class, we only need to create an interface in the
application:
interface ArticleFactory
{
function create(): Article;
}
You can find the full example on GitHub.
Standalone Use
Utilization the Nette DI library in an application is very easy. First we install it with Composer (because downloading zip files is so outdated):
composer require nette/di
The following code creates an instance of the DI container according to the configuration stored in the
config.neon
file:
$loader = new Nette\DI\ContainerLoader(__DIR__ . '/temp');
$class = $loader->load(function ($compiler) {
$compiler->loadConfig(__DIR__ . '/config.neon');
});
$container = new $class;
The container is generated only once, its code is written to the cache (the __DIR__ . '/temp'
directory) and on
subsequent requests it is only read from there.
The getService()
or getByType()
methods are used to create and retrieve services. This is how we
create the UserController
object:
$database = $container->getByType(UserController::class);
$database->query('...');
During development, it is useful to enable auto-refresh mode, where the container is automatically regenerated if any class or
configuration file is changed. Just provide true
as the second argument in the ContainerLoader
constructor.
$loader = new Nette\DI\ContainerLoader(__DIR__ . '/temp', true);
Using It with the Nette Framework
As we have shown, the use of Nette DI is not limited to applications written in the Nette Framework, you can deploy it anywhere with just 3 lines of code. However, if you are developing applications in the Nette Framework, the configuration and creation of the container is handled by Bootstrap.