[英]Laravel: Target is not instantiable while building
抱歉,如果該問題重復,但是我在StackOverflow中閱讀了很多相關問題,但沒有一個解決了我的問題:
我創建了一個有效的Artisan命令,並在其中注入了Kafka客戶端服務作為第一個參數,並注入了一個具體類BudgetsTransformer作為第二個參數
class ConsumeBudgetsCommand extends Command {
public function __construct(FKafka $kafkaClient, BudgetsTransformer $transformer)
{
$this->kafkaClient = $kafkaClient;
$this->transformer = $transformer;
parent::__construct();
}
}
AppServiceProvider類看起來像:
class AppServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->bind('kafka.client', function ($app) {
return new \Weq\FKafka\FKafka();
});
$this->app->bind('budget.transformer', function ($app) {
return new BudgetsTransformer();
});
}
public function boot()
{
$this->app->bind('consume:budgets', function ($app) {
return new ConsumeBudgetsCommand($app['kafka.client'], $app['budget.transformer']);
});
$this->commands('consume:budgets');
}
}
到目前為止,一切工作正常……然后,我決定創建一個由BudgedTransformer
實現的TransformerInterface
(其他將來的Transformers也會實現):
class BudgetsTransformer implements TransformerInterface
{
// ...
}
我在命令中更改了簽名以注入接口而不是具體的類:
class ConsumeBudgetsCommand extends Command {
public function __construct(FKafka $kafkaClient, TransformerInterface $transformer)
{
$this->kafkaClient = $kafkaClient;
$this->transformer = $transformer;
parent::__construct();
}
}
但是當我嘗試運行一些artisan
命令時出現以下問題
在Container.php行933中:在構建[App \\ Console \\ Commands \\ ConsumeBudgetsCommand]時,無法實例化目標[App \\ Transformers \\ TransformerInterface]。
我以前運行以下工匠命令運行此問題,以防萬一... cache:clear
, clear-compiled
, optimize
等,但是沒有運氣
我做錯了什么? 我是否應該以與傳遞和接口(而不是具體的類)不同的方式綁定BudgetTransformer
?
在此先感謝您的幫助
更新資料
正如@davit建議的那樣,我添加了
$this->app->bind(TransformerInterface::class, BudgetsTransformer::class);
在AppServiceProvider :: register()中,我刪除了
$this->app->bind('budget.transformer', function ($app) {
return new BudgetsTransformer();
});
在那里,然后我在AppServiceProvider :: boot()中更新命令綁定:
$this->app->bind('consume:budgets', function ($app) {
return new ConsumeBudgetsCommand($app['kafka.client'], $app[TransformerInterface::class]);
});
但是仍然無法正常工作,無論如何,這種方法(即使CostTransformer
)也無法解決問題,因為當我想添加另一個不同的轉換器實現時,假設實現TransformerInterface
BudgetTransformer
總是會注入BudgetTransformer
。 因此,閱讀鏈接中的文檔后,我發現Contextual Binding
可能是解決方案,因此我對以下內容表示懷疑:
$this->app
->when(ConsumeBudgetsCommand::class)
->needs(TransformerInterface::class)
->give(function ($app) {
return new BudgetsTransformer();
});
因此,通過這種方式,我將能夠通過注入接口將轉換器的不同實現注入不同的命令。 但仍然無法正常工作。
有人可以告訴我如何精確聲明命令綁定
$this->app->bind('consume:budgets', function ($app) {
return new ConsumeBudgetsCommand($app['kafka.client'], ???);
});
使用Contextual binding
?
對於綁定接口,必須使用此結構https://laravel.com/docs/5.5/container#binding-interfaces-to-implementations
$this->app->bind(TransformerInterface::class, BudgetsTransformer::class);
和
$this->app->bind('consume:budgets', function ($app) {
return new ConsumeBudgetsCommand($app['kafka.client'], $app->make(TransformerInterface::class));
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.