Assembly
This repository is experimental, (*1)
Assembly provides an implementation for definition-interop definitions as well as a compatible container., (*2)
, (*3)
Installation
composer require mnapoli/assembly@dev
Usage
While you can implement Interop\Container\Definition\DefinitionProviderInterface
and return an array of definition objects built manually, Assembly provides a natural API to create definitions more easily., (*4)
To take advantage of this, simply extend Assembly\ArrayDefinitionProvider
and fill the getArrayDefinitions
method:, (*5)
class MyModuleDefinitionProvider extend \Assembly\ArrayDefinitionProvider
{
public function getArrayDefinitions()
{
return [
'logger.destination' => '/var/log/myapp.log',
'logger' => \Assembly\object('MyLogger')
->setConstructorArguments('warning', \Assembly\get('logger.destination'))
->addMethodCall('setDebug', true),
'super_mailer' => \Assembly\factory('MailerFactory', 'create'),
'mailer' => \Assembly\get('super_mailer'),
];
}
}
If you are using PHP 5.6 or above, you can import namespaced functions:, (*6)
use function \Assembly\object;
use function \Assembly\get;
class MyModuleDefinitionProvider extend \Assembly\ArrayDefinitionProvider
{
public function getArrayDefinitions()
{
return [
'logger' => object(MyLogger::class),
'logger_alias' => get('logger'),
];
}
}
If you do not want to write a new class, you can also instantiate a new provider directly:, (*7)
$provider = new ArrayDefinitionProvider([
// add definitions here
]);
Definition classes
If you do not want to use the function helpers, you can also create definition instances directly., (*8)
ParameterDefinition
return [
'db.port' => new ParameterDefinition(3306),
];
This definition will define a container entry "db.port"
. That means get('db.port')
will return 3306
., (*9)
Reference
return [
'logger' => new Reference('monolog'),
];
This definition will alias the entry "logger" to the entry "monolog". That means that get('logger')
will return the result of get('monolog')
., (*10)
ObjectDefinition
$definition = new ObjectDefinition('PDO');
$definition->addConstructorArgument('mysql:host=localhost;dbname=test');
$definition->addConstructorArgument('user');
$definition->addConstructorArgument('password');
The definition above will return the result of new PDO('mysql:host=localhost;dbname=test', 'user', 'password')
., (*11)
References can also be used:, (*12)
$definition = new ObjectDefinition('PDO');
$definition->addConstructorArgument(new Reference('db.connection_string'));
$definition->addConstructorArgument('user');
$definition->addConstructorArgument('password');
The definition above will return the result of new PDO($container->get('db.connection_string'), 'user', 'password')
., (*13)
FactoryCallDefinition
The definition below will call the create()
method on the db.factory
container entry and return its result:, (*14)
$definition = new FactoryCallDefinition(new Reference('db.factory'), 'create');
$definition->setArguments(new Reference('db.connection_string'), 'user', 'password');
The definition below will call the static Acme\DbFactory::create()
method:, (*15)
$definition = new FactoryCallDefinition('Acme\DbFactory', 'create');
Container
Assembly ships with a simple container that is compatible with the standard definitions. The goal of this container is to provide a very easy way to get started for those wanting to consume definitions., (*16)
Here is how to use it:, (*17)
// List the definition providers to load
$definitionProviders = [
new Module1DefinitionProvider(),
new Module2DefinitionProvider(),
];
// Define here container entries for the application
$entries = [
'abc' => 'def',
'router' => new Router(...),
];
$container = new Container($entries, $definitionProviders);
For simplicity's sake, the container is immutable and its API is very limited. You are encouraged to use any other compatible container if you are left unsatisfied., (*18)
Definition resolver
The "definition resolver" of the container is written in a separate Assembly\Container\DefinitionResolver
class. This class is meant to be reused in any other container that wishes to support definition-interop. Using it is very simple:, (*19)
$resolver = new \Assembly\Container\DefinitionResolver($container);
$value = $resolver->resolve($definition);