douxian0008
2019-06-17 07:00
浏览 471
已采纳

从命令调度作业时无法实例化接口

I wrote a custom artisan command in my Laravel app, which dispatches a Job. The job has a service dependency in it's handle() method which is resolved via Laravel's DI mechanism. The dependency is injected properly when running the app normally, however, when I try to run php artisan my:command from terminal, I get an error like this:

Symfony\Component\Debug\Exception\FatalThrowableError(code: 0): Cannot instantiate interface App\Services\ABCInterface at /Users/john/code/laravel-project/app/Providers/ABCServiceProvider.php:28)

Here is my the register() method of ABCServiceProvider (Please read the comments also):

public function register()
{
    $this->app->bind(ABCInterface::class, function ($app) {
        if ($app->environment(['testing', 'local'])) {

            // The following log statement is executed when the app runs normally.
            // But isn't executed when the artisan command is run from the console.
            \Log::debug('Instantiating FakeABCService'); 

            // The following class implements ABCInterface.
            return new FakeABCService;

        } else {

            // The following class implements ABCInterface.
            return new ABCService;
        }
    });
}

The handle() method of the Job being dispatched:

public function handle(ABCInterface $abcService)
{
    //
}

Finally, the handle() method of the artisan command class:

/**
 * Execute the console command.
 *
 * @return mixed
 */
public function handle()
{
    $post = Post::first();

    if ($this->confirm("Are you sure?")) {
        MyJob::dispatch($post);
        $this->comment('Done!');
        return;
    }
}

Also, If I inject the dependency (type-hint) to The handle() method of the command class, laravel can resolve it. It's just the Job class' handle() method that's failing to resolve the dependency.

Why is it that the bound class is being resolved in normal application flow, but failing to be resolved when running the command? How can I fix this?

图片转代码服务由CSDN问答提供 功能建议

我在我的Laravel应用程序中编写了一个自定义工匠命令,该应用程序调度了一个Job。 该作业在 handle()方法中具有服务依赖性,该方法通过Laravel的DI机制解决。 正常运行应用程序时正确注入依赖项,但是,当我尝试从终端运行 php artisan my:command 时,我收到如下错误:

Symfony \ Component \ Debug \ Exception \ FatalThrowableError(代码:0):无法在/Users/john/code/laravel-project/app/Providers/ABCServiceProvider.php:28实例化接口App \ Services \ ABCInterface )

这是 ABCServiceProvider register()方法(请同时阅读评论):

  public function register()
 {
 $ this-> app-> bind(ABCInterface :: class,function($ app){
 if(  $ app-> environment(['testing','local'])){
 
 //当应用程序正常运行时,将执行以下日志语句。
 //但是当artisan命令时不执行 从控制台运行。
 \ Log :: debug('实例化FakeABCService'); 
 
 //以下类实现ABCInterface。
 返回新的FakeABCService; 
 
} else {
 
 //以下类实现ABCInterface。
返回新的ABCService; 
} 
}); 
} 
    
 
 

正在调度的作业的 handle()方法:

 公共函数句柄(ABCInterface $ abcService)
 {  
 // 
} 
   
 
 

最后,artisan命令类的 handle()方法:

  / ** 
 *执行控制台命令。
 * 
 * @return mixed 
 * / 
 npublic function handle()
 {
 $ post = Post :: first  (); 
 
 if($ this-> confirm(“你确定吗?”)){
 MyJob :: dispatch($ post); 
 $ this-> comment('Done!')  ; 
返回; 
} 
} 
   
 
 

另外,如果我将依赖项(type-hint)注入 handle()命令类的方法,laravel可以解决它。 它只是Job类的handle()方法无法解决依赖关系。

为什么在正常的应用程序流中解析绑定类,但在运行时无法解析 命令? 我该如何解决这个问题?

  • 写回答
  • 好问题 提建议
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • douqiao6563 2019-06-17 08:10
    已采纳

    Since the Job's handle function is resolved in the queue, try restarting your queue worker.

    Once you have made changes to your code, you have to restart the queue worker for your changes to take effect on the queue.

    Remember, queue workers are long-lived processes and store the booted application state in memory. As a result, they will not notice changes in your code base after they have been started. So, during your deployment process, be sure to restart your queue workers.

    Check the documentation.

    已采纳该答案
    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题