Laravel:服务提供者中接口的条件绑定未按预期工作

问题描述 投票:0回答:1

我正在使用 Laravel(版本 11)并尝试有条件地将接口(

DashboardStrategy
)绑定到不同的具体实现(
DashboardWebService
DashboardApiService
),具体取决于正在解析的控制器(
DashboardWebController
DashboardApiController
)。

问题:

我遇到以下错误:

Target [App\Services\Dashboard\DashboardStrategy] is not instantiable while building [App\Http\Controllers\Dashboard\DashboardWebController].

我已按如下方式设置我的

AppServiceProvider

public function boot(): void
{
    // Inject DashboardApiService for DashboardStrategy when resolving DashboardApiController
    $this->app->when(DashboardApiController::class)
        ->needs(DashboardStrategy::class)
        ->give(DashboardApiService::class);

    // Inject DashboardWebService for DashboardStrategy when resolving DashboardWebController
    $this->app->when(DashboardWebController::class)
        ->needs(DashboardStrategy::class)
        ->give(DashboardWebService::class);
}

public function register(): void
{
    $this->app->singleton(DashboardApiService::class, function (Application $app) {
        return new DashboardApiService($app->make(ImageService::class));
    });

    $this->app->singleton(DashboardWebService::class, function (Application $app) {
        return new DashboardWebService($app->make(ImageService::class));
    });
}

尽管如此设置,Laravel 仍然会抛出上述错误。

我尝试过的:

  1. 将绑定简化如下,并且有效:

    $this->app->singleton(DashboardStrategy::class, DashboardApiService::class);
    

    但是,这会迫使两个控制器使用相同的服务,这是我想避免的。

  2. 清除所有缓存:

    php artisan config:cache
    php artisan route:cache
    php artisan view:cache
    php artisan cache:clear
    php artisan clear-compiled
    
  3. 仔细检查

    DashboardServiceManager
    中的构造函数以确保它期待
    DashboardStrategy
    :

    public function __construct(DashboardStrategy $dashboardStrategy)
    {
        $this->dashboardStrategy = $dashboardStrategy;
    }
    

问题:

如何正确设置条件绑定,以便在解析

DashboardWebService
时注入
DashboardWebController
,并在解析
DashboardApiService
时注入
DashboardApiController

Laravel 中是否有更好的方法来处理这种情况,或者我在当前的实现中遗漏了一些东西?

php laravel dependency-injection dependencies laravel-11
1个回答
0
投票

我认为

give()
需要一个实例,因此您可以尝试这种格式,因为您已经声明了单例

public function boot(): void
{
    // Inject DashboardApiService for DashboardStrategy when resolving DashboardApiController
    $this->app->when(DashboardApiController::class)
        ->needs(DashboardStrategy::class)
        ->give(app(DashboardApiService::class));

    // Inject DashboardWebService for DashboardStrategy when resolving DashboardWebController
    $this->app->when(DashboardWebController::class)
        ->needs(DashboardStrategy::class)
        ->give(app(DashboardWebService::class));
}
© www.soinside.com 2019 - 2024. All rights reserved.