laravel module 接口不能实例化解决办法

背景

laravel 项目在测试服务器报错

Target [Modules\Chip\Repository\ChipServiceInterface] is not instantiable while building [App\Http\Controllers\Api\Service\ChipController].

前提是已经在对应 module 的 ServiceProvider 中绑定了该接口实例化的类

namespace Modules\Chip\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Database\Eloquent\Factory;
use Modules\Chip\Repository\ChipService;
use Modules\Chip\Repository\ChipServiceInterface;

class ChipServiceProvider extends ServiceProvider
{
    ...
    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        $this->app->register(RouteServiceProvider::class);
        $this->app->bind(ChipServiceInterface::class,ChipService::class);
    }    
}

解决办法

从报错反推来看,是ServiceProvider没有被正确加载的问题,所以在 config/app.php 里添加上 \Modules\Chip\Providers\ChipServiceProvider::class, 即可解决

    /*
    |--------------------------------------------------------------------------
    | Autoloaded Service Providers
    |--------------------------------------------------------------------------
    |
    | The service providers listed here will be automatically loaded on the
    | request to your application. Feel free to add your own services to
    | this array to grant expanded functionality to your applications.
    |
    */

    'providers' => [
        ...
        \Modules\Chip\Providers\ChipServiceProvider::class,
    ]

由于本地没有出现这个问题,而代码传到测试服就会报这个错,从而代码比对本地与测试服的区别找问题。
排查出来的结果是测试服上缺少了 storageappmodules_statuses.json 这个文件,文件的内容如下:

{
    "User": true,
    "Game": true,
    "Activity": true,
    "Article": true,
    "Chip":true
}

从项目中全局找文件被引用的代码,即可发现在 vendornwidartlaravel-modulesconfig 有引用到:

    /*
    |--------------------------------------------------------------------------
    | Activators
    |--------------------------------------------------------------------------
    |
    | You can define new types of activators here, file, database etc. The only
    | required parameter is 'class'.
    | The file activator will store the activation status in storage/installed_modules
    */
    'activators' => [
        'file' => [
            'class' => FileActivator::class,
            'statuses-file' => storage_path('app/modules_statuses.json'),
            'cache-key' => 'activator.installed',
            'cache-lifetime' => 604800,
        ],
    ],

出现问题的原因是 storage/ 作为缓存目录,已经被忽略添加到git版本控制中了。
而使用 php artisan module:make Chip 创建 module 的时候则会在 storageappmodules_statuses.json 这个文件中生成一行 "Chip":true

所以解决方法只需要把 storageappmodules_statuses.json 这个文件传到服务器或者加入到版本控制中即可。

Responses
  1. I'm not sure where you are getting your information, but good topic. I needs to spend some time learning much more or understanding more. Thanks for wonderful information I was looking for this information for my mission.

    Reply
  2. Hello there! This is kind of off topic but I need some guidance from an established blog. Is it tough to set up your own blog? I'm not very techincal but I can figure things out pretty quick. I'm thinking about creating my own but I'm not sure where to start. Do you have any points or suggestions? Appreciate it

    Reply
  3. magnificent put up, very informative. I'm wondering why the opposite experts of this sector do not understand this. You must proceed your writing. I am confident, you have a great readers' base already!

    Reply
  4. When someone writes an article he/she retains the plan of a user in his/her mind that how a user can be aware of it. Thus that's why this paragraph is great. Thanks!

    Reply
  5. We're a group of volunteers and opening a new scheme in our community. Your website offered us with helpful info to work on. You've performed a formidable activity and our entire community will probably be thankful to you.

    Reply
  6. Why visitors ѕtill use to read news papers when in thiѕ tеchnologicаl globe thee whole thing iss accessible on net?

    Reply