我正在使用 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 仍然会抛出上述错误。
我尝试过的:
将绑定简化如下,并且有效:
$this->app->singleton(DashboardStrategy::class, DashboardApiService::class);
但是,这会迫使两个控制器使用相同的服务,这是我想避免的。
清除所有缓存:
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan cache:clear
php artisan clear-compiled
仔细检查
DashboardServiceManager
中的构造函数以确保它期待DashboardStrategy
:
public function __construct(DashboardStrategy $dashboardStrategy)
{
$this->dashboardStrategy = $dashboardStrategy;
}
问题:
如何正确设置条件绑定,以便在解析
DashboardWebService
时注入DashboardWebController
,并在解析DashboardApiService
时注入DashboardApiController
?
Laravel 中是否有更好的方法来处理这种情况,或者我在当前的实现中遗漏了一些东西?
我认为
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));
}