The ContainerBuilder also builds fully-configured Container objects using ContainerConfig classes. It works using a two-stage configuration system.
The two stages are "define" and "modify". In the "define" stage, the ContainerConfig object defines constructor parameter values, setter method values, services, and so on. The ContainerBuilder then locks the Container so that these definitions cannot be changed, and begins the "modify" stage. In the "modify" stage, we may get()
services from the Container and modify them programmatically if needed.
To build a fully-configured Container using the ContainerBuilder, we do something like the following:
use Aura\Di\ContainerBuilder;
$container_builder = new ContainerBuilder();
// use the builder to create and configure a container
// using an array of ContainerConfig classes
$di = $container_builder->newConfiguredInstance([
'Aura\Cli\_Config\Common',
'Aura\Router\_Config\Common',
'Aura\Web\_Config\Common',
]);
Note: As with the newInstance
method of the ContainerBuilder
, you will have to pass $container_builder::AUTO_RESOLVE
to newConfiguredInstance
(as the second parameter) if you want to enable auto-resolution.
A configuration class looks like the following:
namespace Vendor\Package;
use Aura\Di\Container;
use Aura\Di\ContainerConfig;
class Config extends ContainerConfig
{
public function define(Container $di)
{
$di->set('log_service', $di->lazyNew('Logger'));
$di->params['Logger']['dir'] = '/path/to/logs';
}
public function modify(Container $di)
{
$log = $di->get('log_service');
$log->debug('Finished config.');
}
}
Here are some example ContainerConfig classes from earlier Aura packages:
Alternatively, if you already have a ContainerConfig object created, you can pass it directly to the ContainerBuilder instead of a string class name:
$routerConfig = new Aura\Router\_Config\Common();
// use the builder to create and configure a container
// using an array of ContainerConfig classes
$di = $container_builder->newConfiguredInstance([
'Aura\Cli\_Config\Common',
$routerConfig,
'Aura\Web\_Config\Common',
]);
If you have a package which combines a number of disparate components that
each provide a ContainerConfig
you could bundle them together using the
ConfigCollection
class. This class takes an array of ContainerConfig
s or
ContainerConfig
class names and implements ContainerConfigInterface
itself.
namespace My\App;
use Aura\Di\ConfigCollection;
use My\Domain;
use My\WebInterface;
use My\DataSource;
class Config extends ConfigCollection
{
public function __construct()
{
parent::__construct(
[
Domain\Config::class,
WebInterface\Config::class,
DataSource\Config::class,
]
);
}
}
You can then use the Collection and it will instantiate (if necessary) and call
the define
and modify
methods of each of the other ContainerConfigs.
$di = $container_builder->newConfiguredInstance([\My\App\Config::class])