factory
factory copied to clipboard
More comfortable way to create an object using a factory
$factory->create(EngineInterface::class, 146);
instead of
$factory->create([
'class' => EngineInterface::class,
'__construct()' => [
'power' => 146,
],
]);
https://github.com/yiisoft/factory/blob/master/src/Factory.php#L102
As I can see it's almost possible now to create a class with only class reference, but the rest params must be two arrays:
- params for constructor method
- the rest configuration of methods calls and etc
So I'd suggest to make it possible to use add a few options params and the merge it into another one so it can convert into the original structure:
$f->create(MyClass::class, ['userId' => 5], ['setUserId()' => [5]]);
function create(mixed $config); // before
function create(mixed $config, array $constructor = [], array $restConfig = []) // after
{
if (is_string($config) && !empty($constructor) && !empty($restConfig)) {
$config = ['__class' => $config, ...array_merge($restConfig, ['__construct()' => $constructor])];
}
... // original function body
}
As we create a concrete instance, no need to pass ['setUserId()' => [5]].
I'd preffer this way:
$obj = $f->create(MyClass::class, userId: 5);
$obj->setUserId(10);
function create(mixed $config, mixed ...$constructor)
{
...
}
Agree with @Tigrov. For rest configuration better use PHP syntax.
The only doubt is, is there a case when the rest configuration passed as array? (I think, that no...)
It's not convenient to mix array- and callable- like configurations and use it together. As Factory can make necessary calls it must do it.
If you want to pass rest configuration, you can use as it is now
$factory->create([
'class' => EngineInterface::class,
'__construct()' => [
'power' => 146,
],
'setUserId()' => [5],
]);
Or
$factory->create([
'class' => EngineInterface::class,
'setUserId()' => [5],
], power: 146);
For sure. But the issue is about to make factory flexible for creating objects by instructions.
I don't like various parameters for constructors at all. It would just make the method unavailable for further modifications, as we have now: create($config) -> create($config, $constructor) -> create($config, $constructor, $rest) -> create($config, $constructor, $rest, $flags) and so on.
Let's stop propagate this way?
$factory->create([ 'class' => EngineInterface::class, 'setUserId()' => [5], ], power: 146);
I don't like this way, because it requires merge constructor arguments when config also contain them.
May be create separate method with suggested syntax?
it requires merge constructor arguments when config also contain them.
I don't see anything wrong with this.
May be create separate method with suggested syntax?
Maybe
May be create separate method with suggested syntax?
Yes. That's better. When designing the syntax, we've tried mixing formats in the same call, but then dropped it completely. Merging these was creating hell.