Main changes:
Rename a few helpers to actions:
factory()
->call()
object()
->create()
This is hopefully clearer on what will actually be done.
Same for object()
methods:
->constructor(...)
->->parameters(...)
->method(...)
->->call(...)
object()
is too magic (extends autowiring and other definitions). We can split its behavior into:
create()
: create an object, doesn't extend autowiring or a previous definitionautowire()
: create an object using autowiring, also allows to set some parameters/method callsextend()
: extend the previous definition to override constructor parameters/method calls
It will be much clearer (less suprises is always better), and we'll be able to add support for "explicit autowiring" where you only get autowiring when using autowire()
, which I think is really good when you don't want too much magic.
Add a way to set parameters on call()
: call(function (...) {...})->parameters(get('abc'), get('def'))
.
Summary:
return [
'foo' => get('bar'),
'foo' => env('FOO'),
'foo' => string('{root}/test.txt'),
'foo' => create(MyClass::class),
MyClass::class => create(),
MyClass::class => create()
->with('param1', get('foo'))
->call('setLogger', get(Logger::class)),
'*Repository' => create('*DoctrineRepository'),
'foo' => autowire(MyClass::class),
MyClass::class => autowire()
->parameters(get('abc')),
MyClass::class => autowire()
->parameter('param1', get('abc')),
MyClass::class => autowire()
->call('setLogger', get(Logger::class)),
'bar' => extend('foo')
->parameter('param2', get('def')),
'bar' => extend()
->call('setLogger', get(Logger::class)),
'foo' => call(function () {
return 'bar';
}),
'foo' => call([Factory::class, 'method']),
'foo' => call([Factory::class, 'method'])
->parameters(get('abc')),
'foo' => call([Factory::class, 'method'])
->parameter('param1', get('abc')),
'api' => decorate(function ($previous, $c) {
return new CachedApi($previous);
}),
'log.handlers' => [
get(StreamHandler::class),
get(EmailHandler::class),
],
'log.handlers' => add([
get(SyslogHandler::class),
]),
];
Internal changes:
The configuration array could be turned into an AST and visitors could be applied (to turn it into a proper definition array). Then the resulting processed array of definitions could be cached.
Autowiring and annotation reader might not be "definition source" anymore (so much trouble from the beginning because of this).
That should solve problems of definitions nested in others (#297, #343), making caching easier and much more efficient (cache one array instead of each definition separately), maybe open the door for AST extensions, maybe open the door to compiling?
That config-to-AST part could be written as a separate package. It allows to write any configuration using PHP arrays, it could be useful. For example I needed exactly that for a framework and started a draft of such a thing (https://github.com/stratifyphp/framework/tree/master/src/Config).