很抱歉,如果该问题重复,但是我在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');
}
}
到目前为止,一切工作正常……然后,我决定创建一个TransformerInterface
实现的BudgedTransformer
(其他将来的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
的{{1}}总是会注入{ {1}}。因此,阅读链接中的文档后,我发现TransformerInterface
可能是解决方案,所以我对此感到怀疑:
BudgetTransformer
因此,通过这种方式,我将能够通过注入接口将转换器的不同实现注入不同的命令。但仍然无法正常工作。
有人可以告诉我如何精确声明命令绑定
Contextual Binding
使用那个$this->app
->when(ConsumeBudgetsCommand::class)
->needs(TransformerInterface::class)
->give(function ($app) {
return new BudgetsTransformer();
});
?
答案 0 :(得分:2)
对于绑定接口,必须使用此结构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));
});