Laravel dependency injection with inheritance

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 with my service provider dependency injection for the abstract parent class of my services?

I have an API that is dynamically generated from a BOM and each of these classes must extend abstract Service

so that it can inherit core functionality.

How can I inject dependencies into my abstract service when creating a child service?


EDIT: This question was specifically asked to introduce an abstract class without the ability to bind child classes that are automatically generated.

+3


source to share


2 answers


In your example, you need to manually pass an object config

every time you instantiate a class Service

or child class.

So, if you want to create a child service directly, you can use something like $cs = new ClientService(new Config());

However, you can take the real advantage of DI (since you are using Laravel), by the type hinting at the class name in the constructor, as shown below.

public function __construct(\Config $config)

      



This way, if you don't pass a parameter when instantiating, it will by default create an object of the class with the intended type and add it. So you could use it like.

$cs = new ClientService();

This will inject the Laravel instance config

into the object ClientService

.

+2


source


There are two possible things here. First, if $config

is a class, you can inject it into an abstract class:

abstract class Service {

    protected $config;

    public function __construct(ClassName $config)
    {
        $this->config = $config;
    }
}

      

Then every time the child classes are solved by injection or calling App::make('ClientService')

, a config class will be added.



If the configuration is not a class and cannot be specified in the type, you will have to bind the child classes in 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);
});

      

You can then call App::make('ClientService')

or resolve it using DI.

+2


source







All Articles