I'm wondering how (if I can) register a shared service with a custom factory.
Consider the following code:
class MyApiFactory {
private $config;
public function ___construct(Config $config) {
$this->config = $config;
}
//this method could either be __invoke
//or the class could implement some factory interface
public function create() {
return new MyApi($this->config->get('some-value'), $this->config->get('some-other-value'));
}
}
class MyApi {
}
class MyService1 {
public function __construct(MyApi $api) {}
}
class MyService2 {
public function __construct(MyApi $api) {}
}
With other PHP DI frameworks - I would register MyApiFactory
as a factory for MyApi
. If I requested for service MyService1
the DI container would see that It needs MyApi
and therefore execute MyApiFactory
to get MyApi
- MyApi
would then be stored as a service (if the container supports sharing).
Then I ask for MyService2
which also needs MyApi
- as MyApi
has already been created before - it just pulls it from the DI container and injects it in MyService2
.
Therefore MyApi
in MyService1
& MyService2
are the same.
I can't seem to find a way to do this in Magento 2. Basically I want to avoid creating MyApi
twice.
The only way I can think to do this is to keep a record of the created MyApi
inside MyApiFactory
so the second time MyApiFactory::create
is called it returns the existing instance. Then I would have to inject MyApiFactory
into MyService1
& MyService2
and call create
within there constructors or wherever.
This (to me) seems wholly unnecessary and quite unintuitive - is this a problem anyone else has come across? Is there some support for shared services with custom factories in Magento 2 ?
This was more of a question to the Magento 2 developers rather than the community, I did originally create this as an issue but that got shut down, refs: https://github.com/magento/magento2/issues/8182#issuecomment-273763661
MyApi
is not a singleton in my case, there is an instance per website with different configuration.