Связанный класс, не разрешающийся в пакете

#laravel #laravel-8 #laravel-service-container

Вопрос:

У меня есть класс API, который привязан к контейнеру через поставщика услуг:

 public function register()
{
    $this->app->bind('apiclient', fn($app) => new APIClient($app));
}
 

Он не определен как пакет 'app/config/app.php' , как в файле packages.json.

Он построен с $app использованием параметра в URL — адресе, который используется для переключения параметра base_uri, используемого API для своих запросов, аналогично тому, как приложение Spatie для нескольких арендаторов использует параметр в URL-адресе для переключения между базами данных наземной загрузки.

Все это работает на протяжении всего приложения, как и ожидалось, вот так:

 $user = APIClient::get()
->class('users')
->routing('/123123/123123/123123')
->getResult();
 

Я не считаю, что внутренняя работа класса API важна, так как, по сути, методы используются для создания полного URI и / или любых требуемых данных POST — если я ошибаюсь, дайте мне знать, и я обновлю.

В любом случае, вопрос на повестке дня. Я собираюсь использовать API для аутентификации пользователей с помощью двух новых поставщиков пользователей, которые я добавил app/congif/auth.php , как это

 'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'sl_business',
        ],
]
///
'providers' => [
        'sl_business' => [
            'driver' => 'sl_business'
        ]
]
 

Где 'sl_business' зарегистрирован в качестве поставщика аутентификации:

 Auth::provider('sl_business', function ($app, array $config) {
    // Return an instance of IlluminateContractsAuthUserProvider...
    return new EmployeeUserProvider($this->app['hash'], $config['model']);
});
 

Запрос на вход корректно использует этого поставщика пользователей, однако поставщик EmployeeUserProvider не может использовать этот APIClient класс. Следующее, что хорошо работает в «приложении», не разрешает класс в пакете:

 $user = APIClient::get()
        ->class('employee')
        ->endPoint('login')
        ->route('/'.$loginid.'/'.$password.'/')
        ->getResult();
 

Когда я отлаживаю с dd(resolve(APIClient::class)); помощью , я получаю:

 Target class [BusinessAPIAuthProvidersAIPClient] does not exist.
 

BusinessAPIAuthProviders является пространством имен поставщика, в котором я работаю, и нет, AIPClient не существует в этом каталоге, он существует внутри BusinessAPI .

Все эти файлы находятся в одном пакете, поэтому я предполагаю, что пытаюсь определить наилучший способ разрешения класса из приложения в моем пакете, или, если это вообще возможно.

Ответ №1:

Я изменил метод построения класса, чтобы принять ApiClient в качестве аргумента, и изменил регистрацию поставщика, включив в нее указанного клиента:

 Auth::provider('sl_business', function ($app, array $config) {
    // Return an instance of IlluminateContractsAuthUserProvider...
    return new EmployeeUserProvider($this->app['hash'], $config['model'], new APIClient($this->app));
});   

 

И конструктор:

 public function __construct(HasherContract $hasher, $model, APIClient $api)
{
    $this->model = $model;
    $this->hasher = $hasher;
    $this->api = $api;
}
 

Теперь я могу получить доступ к ApiClient через провайдера пользователей, как $this->api