I have services that depend on request information. I'm trying to create a Factory Factory which will have the Dependency Injection container returns a factory (an anonymous function) that will create the services I want. So basically somthing like this:
class FooFactoryFactory {
public static function create(ContainerInterface $container): callable {
return static function (Request $request) use ($container) {
$raz = request->get('param_raz');
return new Bar(
$container->get(LoggerInterface::class),
$raz,
);
};
}
}
The issue I have is that the Closure
is properly created, but de Drupal's Dependency Injection Container class tries to set a proprty to the Closure
. This cannot work and ends in a fatal error:
Closure object cannot have properties
Here is the place where it occurs:
// Drupal\Component\DependencyInjection\Container::createService() - Line 283-293
if (isset($definition['properties'])) {
if ($definition['properties'] instanceof \stdClass) {
$definition['properties'] = $this->resolveServicesAndParameters($definition['properties']);
}
foreach ($definition['properties'] as $key => $value) {
$service->{$key} = $value; // <-- Will not work for Closure
}
}
...
So the questions I have:
- Is this by design? Meaning is it something thta is not wanted in term of coding practice?
- The error can be avoided if I manage to make sure, that the service I want to create does not have
properties
it it's definition. I just don't know how to achieve this.
Thanks for the help on this matter.
EDIT: This is basically what I'm trying to achieve:
closure.factory.service:
class: Drupal\some_module\ClosureFactoryService
closure.service:
class: Closure
factory: [ '@closure.factory.service', getCallable ]
class ClosureFactoryService {
public function getCallable(): Closure {
return static function (int $arg): string {
return sprintf('val %d', $arg);
};
}
}
I get: Closure object cannot have properties in Drupal\Component\DependencyInjection\Container->createService() (line 288...
@request_stack
To understand your design, can you provide the entire code, specifically the Bar class and the service definition causing the error. Why are you using this specific factory method? Can you provide more context?Drupal\Component\DependencyInjection\Container.php
. @4k4: that's pretty much it in the example. The services I want to need to have dependencies pulled form the container and depends on the container. Is it something that is not allowed to be implemented that way?create()
method. The Dependency Injection used by Drupal, which is Symfony Dependency Injection, expectscreate()
to return an instance of that class, not a closure.*.yml
files because that is not where I'm having issuef. The challenge I have is to return an anonymous (factory) function from the following Drupal's classDrupal\Component\DependencyInjection\Container.php
. I've posted the piece of code in that class that make it fails. TheClosure
is properly created in the mentioned Drupal class but the next lines makes theContainer.php
throw an error. I'll check the container implementation of Symfony.