Laravel:在构建时无法实例化目标 [英] Laravel: Target is not instantiable while building
问题描述
很抱歉,如果该问题重复,但是我在StackOverflow中阅读了很多相关问题,但没有一个解决了我的问题:
Sorry if that question is duplicate, but I've read a lot of related question in StackOverflow but none solved my problem:
我创建了一个Artisan命令,该命令有效,并在其中注入了Kafka客户服务作为第一个参数,并注入了具体类BudgetsTransformer作为第二个参数
I created an Artisan command which worked and where I injected a Kafka client service as 1st param and a concrete class, BudgetsTransformer, as the 2nd parameter
class ConsumeBudgetsCommand extends Command {
public function __construct(FKafka $kafkaClient, BudgetsTransformer $transformer)
{
$this->kafkaClient = $kafkaClient;
$this->transformer = $transformer;
parent::__construct();
}
}
AppServiceProvider类如下:
AppServiceProvider class looked like:
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');
}
}
到目前为止,一切都工作正常...然后,我决定创建一个TransformerInterface
,它由BudgedTransformer
实现(其他将来的Transformers也会实现):
So far all is working properly... Then I decided to create a TransformerInterface
which BudgedTransformer
implements (and other future Transformers will implement it):
class BudgetsTransformer implements TransformerInterface
{
// ...
}
我更改了命令中的签名以注入接口,而不是具体的类:
and I changed the signature in the command to inject the interface instead of the concrete class:
class ConsumeBudgetsCommand extends Command {
public function __construct(FKafka $kafkaClient, TransformerInterface $transformer)
{
$this->kafkaClient = $kafkaClient;
$this->transformer = $transformer;
parent::__construct();
}
}
但是当我尝试运行一些artisan
命令
But I get the following issue when I try to run some artisan
command
在Container.php第933行中: 构建[App \ Console \ Commands \ ConsumeBudgetsCommand]时,无法实例化目标[App \ Transformers \ TransformerInterface].
In Container.php line 933: Target [App\Transformers\TransformerInterface] is not instantiable while building [App\Console\Commands\ConsumeBudgetsCommand].
我以前会运行以下工匠命令,以防万一... cache:clear
,clear-compiled
,optimize
等,但是没有运气
I run previously the issue the following artisan command just in case... cache:clear
, clear-compiled
, optimize
and so on but no luck
我做错了什么?我应该用现在为传递和接口而不是具体的类采用的其他方式绑定BudgetTransformer
吗?
What I'm doing wrong? Should I bind the BudgetTransformer
in a different way I'm doing now for passing and Interface instead of a concrete class?
预先感谢您的帮助
更新
按照@davit的建议,我添加了
As @davit suggested, I added
$this->app->bind(TransformerInterface::class, BudgetsTransformer::class);
在AppServiceProvider :: register()中,我删除了
in AppServiceProvider::register() and I removed
$this->app->bind('budget.transformer', function ($app) {
return new BudgetsTransformer();
});
在那里,然后在AppServiceProvider :: boot()中更新命令绑定:
there, then I update in AppServiceProvider::boot() the command binding:
$this->app->bind('consume:budgets', function ($app) {
return new ConsumeBudgetsCommand($app['kafka.client'], $app[TransformerInterface::class]);
});
但是仍然无法正常工作,无论如何,这种方法(即使可行)也无法解决问题,因为当我想添加另一个不同的转换器实现时,假设实现了TransformerInterface
的CostTransformer
总是会注入BudgetTransformer
.因此,阅读链接中的文档后,我发现Contextual Binding
可能是解决方案,所以我对此表示怀疑:
But still not working, anyway this approach (even working) will not resolve the issue since when I want to add another different transformer implementation, let's say CostTransformer
which implements TransformerInterface
is gonna always inject BudgetTransformer
. So reading the documentation in the link, I found that Contextual Binding
could be the solution, so I sustituded by:
$this->app
->when(ConsumeBudgetsCommand::class)
->needs(TransformerInterface::class)
->give(function ($app) {
return new BudgetsTransformer();
});
因此,通过这种方式,我将能够通过注入接口来将转换器的不同实现注入到不同的命令中.但仍然无法正常工作.
So in that way, I will be able to inject different implementations of transformers to different commands by injecting the interface. But still not working.
有人可以告诉我如何精确声明命令绑定
Can someone tell me how exactly declare the command binding
$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
For binding interfaces must be use this structure 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));
});
这篇关于Laravel:在构建时无法实例化目标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!