Reputation: 2530
Let's say I have the following case:
<?php
abstract class Service {
protected $config;
public function __construct($config)
{
$this->config = $config;
}
}
class ClientService extends Service {
}
class ProductService extends Service {
}
Is it possible to register in my service provider the dependency injection for the Abstract parent class of my services ?
I have an API which is generated dynamically from a specification, and each one of those classes must extend the abstract Service
so it can inherit for basic functionalities.
How can I Inject dependencies in my abstract service when I instantiate a child Service ?
EDIT: This question was specifically asked for Abstract class injection, without the possibility to bind the child classes which are generated automatically.
Upvotes: 9
Views: 3168
Reputation: 1464
There are two possible things you could do here. First, if $config
is a class, then you can type hint it in the abstract class:
abstract class Service {
protected $config;
public function __construct(ClassName $config)
{
$this->config = $config;
}
}
Then every time the child classes get resolved via injection or by calling App::make('ClientService')
, the config class will be injected.
If the config is not a class and can't be type hinted, you will have to bind the child classes into the container individually:
App::bind('ClientService', function () {
// Get $config from somewhere first
return new ClientService($config);
});
App::bind('ProductService', function () {
// Get $config from somewhere first
return new ProductService($config);
});
Then you will be able to call App::make('ClientService')
or have it resolved via DI.
Upvotes: 4
Reputation: 3423
In your example, you have to manually pass the config
object every time you instantiate from Service
class or a child class.
So when you want to directly instantiate a child service, you could use something like, $cs = new ClientService(new Config());
However, you can use the real advantage of DI (since you are using Laravel), by type hinting the class name in the constructor like below.
public function __construct(\Config $config)
This way, if you do not pass a parameter when instantiating, it would by default create an object of the type-hinted class and inject it. So you could then use it like.
$cs = new ClientService();
This would inject a Laravel Config
instance into the ClientService
object.
Upvotes: 4