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. Greetings! I've been following your weblog for some time now and finally got the courage to go ahead and give you a shout out from Huffman Tx! Just wanted to say keep up the excellent work!

    Reply
  2. Hi! Do you know if they make any plugins to assist with SEO? I'm trying to get my blog to rank for some targeted keywords but I'm not seeing very good gains. If you know of any please share. Kudos!

    Reply
  3. Hello There. I found your blog using msn. This is a really well written article. I will make sure to bookmark it and come back to read more of your useful info. Thanks for the post. I'll definitely comeback.

    Reply
  4. Thanks for your personal marvelous posting! I certainly enjoyed reading it, you're a great author.I will always bookmark your blog and definitely will come back very soon. I want to encourage you continue your great posts, have a nice weekend!

    Reply
  5. Hi, every time i used to check web site posts here early in the dawn, because i like to find out more and more.

    Reply
  6. I've been browsing online more than 4 hours today, yet I never found any interesting article like yours. It's pretty worth enough for me. In my opinion, if all site owners and bloggers made good content as you did, the internet will be a lot more useful than ever before.

    Reply