Где лучше всего инициализировать библиотеку в Laravel?

Добрый день. В рамках проекта на Laravel идет использование библиотеки для работы с API. На текущий момент я использую "прослойку": сервис из двух методов: _construct и getInstance.
class ApiClient
{
    protected $api;
    public function __construct() {
        $this->api = new VeryUsefulApi([
            '1' => env('1', false),
            '2' => env('2', false),
            '3' => env('3', false),
            '4' => env('4', false),
        ]);
    }

    public function getInstance() {
        return $this->api;
    }
}

В первом автоматически по параметрам из ENV файла происходит инициализация библиотеки и запись в protected поле класса, во втором - просто выдача наружу уже инициализированного объекта. Этот сервис зарегистрирован как singletone. В других сервисах, где необходимо использование этой библиотеки, я использую внедрение зависимостей в конструктор и делаю что-то типа
public function __construct(ApiClient $api) {
        $this->api= $api;
}

и дальше использую уже по месту назначения.
Вопрос: как вы решаете такую задачу и/или как ее нужно решать правильно?
  • Вопрос задан
  • 69 просмотров
Пригласить эксперта
Ответы на вопрос 2
greabock
@greabock
Могу
use Illuminate\Support\ServiceProvider;

class ApiClientServiceProvider extends ServiceProvider 
{
    /** @var boolean  Отложенный, потому не при каждом запросе нам нужно дергать это апи */
    public $deffered = true;

    public function register ( ) 
    {
        
        $this->app->singleton(VeryUsefulApi::class, function($app) {
             // Не очень хорошо дергать env из провайдера, поэтому поместим-ка настройки в конфиг
            // А уж из конфига будем дергать env
            new VeryUsefulApi([$app['config']['services.verify_user']); 
        });

        $this->app->singleton(ApiClient::class); // Ну это если нужен именно синглтон
    }

     /** @return array | string[]  Сообщаем контейнеру, что если вдруг нужны эти ключи, то они тут */
    public function provides() {
        return [VeryUsefulApi::class, ApiClient::class];
    }
}

class ApiClient 
{
    /** @var VeryUsefulApi */
    protected $api;

    public function __construct (VeryUsefulApi $api)  
    {
        $this->api = $api;
    }
    #...
}

class SomeController {

    /** @var ApiClient */
    protected $client;

    public fuction __construct(ApiClient  $client)
    {
          $this->clien = $client;
    }
}

Ну это если буквально то, что вы просили.

С другой стороны, не очень понятно зачем вообще нужна эта обертка.
Почему бы не дергать VeryUsefulApi напрямую, минуя обертку ApiClient.
Ну это так, мысли вслух... "Вам из колодца виднее"(с) )
Ответ написан
orlov0562
@orlov0562
I'm cool!
Примерно так и делается. Только VeryUsefulApi лучше так же внедрять в адаптер через DI, иначе ApiClient получается жестко связан с VeryUsefulApi. Но, я предполагаю, что есть причины почему так сделано.
Если причин нет, то вот тут посмотри как это делается: Laravel's Dependency Injection Container in Depth.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через TM ID
Похожие вопросы