没有不值得去解决的问题,也没有不值得去学习的技术!

BindingResolutionException in Laravel 6, Lighthouse 5, and nwidart/laravel-modules 7: Missing provides Method Causes Provider Deferred Loading to Fail

在 Lighthouse 5 中,报错:Illuminate\Contracts\Container\BindingResolutionException : Target [Interface] is not instantiable while building [Resolver].

1. In Lighthouse 5, the following error occurs: Illuminate\Contracts\Container\BindingResolutionException : Target [Interface] is not instantiable while building [Resolver]. See Figure 1.

In Lighthouse 5, the following error occurs: Illuminate\Contracts\Container\BindingResolutionException : Target [Interface] is not instantiable while building [Resolver].
Figure 1
Plaintext
PS E:\wwwroot\object> php artisan lighthouse:ide-helper
Wrote schema directive definitions to E:\wwwroot\object/schema-directives.graphql.

   Illuminate\Contracts\Container\BindingResolutionException  : Target [Modules\ThemeStoreGraphQl\ThemeSetting\Schema\TemplateSchemaLoaderInterface] is not instantiable while building [Modules\ThemeStoreGraphQl\Resolver\OnlineStoreTheme\TemplateSettingsDataResolver].

  at E:\wwwroot\object\vendor\laravel\framework\src\Illuminate\Container\Container.php:978
    974|         } else {
    975|             $message = "Target [$concrete] is not instantiable.";
    976|         }
    977|
  > 978|         throw new BindingResolutionException($message);
    979|     }
    980|
    981|     /**
    982|      * Throw an exception for an unresolvable primitive.

  Exception trace:

  1   Illuminate\Container\Container::notInstantiable("Modules\ThemeStoreGraphQl\ThemeSetting\Schema\TemplateSchemaLoaderInterface")
      E:\wwwroot\object\vendor\laravel\framework\src\Illuminate\Container\Container.php:812

  2   Illuminate\Container\Container::build("Modules\ThemeStoreGraphQl\ThemeSetting\Schema\TemplateSchemaLoaderInterface")
      E:\wwwroot\object\vendor\laravel\framework\src\Illuminate\Container\Container.php:681

  Please use the argument -v to see more details.

2. Edit ThemeStoreGraphQl/Resources/graphql/theme_setting.graphql and comment out: templateSettingsData(basename: String!): [ThemeSection] @field(resolver: “Modules\\ThemeStoreGraphQl\\Resolver\\OnlineStoreTheme\\TemplateSettingsDataResolver”). The error no longer occurs.

GraphQL
    # "获取主题页面的配置"
    # templateSettingsData(basename: String!): [ThemeSection] @field(resolver: "Modules\\ThemeStoreGraphQl\\Resolver\\OnlineStoreTheme\\TemplateSettingsDataResolver")

3. After uncommenting it, check ThemeStoreGraphQl/Resolver/OnlineStoreTheme/TemplateSettingsDataResolver.php. TemplateSchemaLoaderInterface is passed in as a constructor parameter.

PHP
    private TemplateSchemaLoaderInterface $templateSchemaLoader;

    public function __construct(TemplateSchemaLoaderInterface $templateSchemaLoader)
    {
        $this->templateSchemaLoader = $templateSchemaLoader;
    }

4. Check the service provider class for this module and confirm that the corresponding instance is registered. However, register() is not executed, because graphql is not output.

PHP
    public function register()
    {
        echo 'graphql';
        exit;

        $this->app->singleton(TemplateSchemaLoaderInterface::class, function($app) {
            if ($this->app['config']['theme_store.view_storage'] == 'database') {
                return new DbTemplateSchemaLoader($app->make(ViewStorageInterface::class), $app->make(TemplateBuilder::class));
            } else {
                return new FileTemplateSchemaLoader($app->make('igaster.themes'), $app->make(TemplateBuilder::class));
            }
        });

        $this->app->singleton(TemplateSettingsDataResolver::class, function($app){
            return new TemplateSettingsDataResolver($app->make(TemplateSchemaLoaderInterface::class));
        });

    }

5. Check the module list: its Name is ThemeStoreGraphQL, and its Path is E:\wwwroot\object\Modules/ThemeStoreGraphQl. See Figure 2.

Check the module list: its Name is ThemeStoreGraphQL, and its Path is E:\wwwroot\object\Modules/ThemeStoreGraphQl
Figure 2

6. Check /Modules/ThemeStoreGraphQl/composer.json: the path ThemeStoreGraphQL does not match the actual directory name ThemeStoreGraphQl. Adjust it to match the actual directory name. See Figure 3.

Check /Modules/ThemeStoreGraphQl/composer.json: the path ThemeStoreGraphQL does not match the actual directory name ThemeStoreGraphQl. Adjust it to match the actual directory name
Figure 3
JSON
{

    "extra": {
        "laravel": {
            "providers": [
                "Modules\\ThemeStoreGraphQL\\Providers\\GraphQlResolverServiceProvider"
            ],
            "aliases": {

            }
        }
    },
    "autoload": {
        "psr-4": {
            "Modules\\ThemeStoreGraphQL\\": ""
        }
    }

}


7. Rename the directory to ThemeStoreGraphQL, then batch replace ThemeStoreGraphQl with ThemeStoreGraphQL. Renaming fails in PhpStorm with the prompt: java.io.IOException: 无法将 ‘E:\wwwroot\object\Modules\ThemeStoreGraphQl’重命名为 ThemeStoreGraphQL. See Figure 4.

Rename the directory to ThemeStoreGraphQL, then batch replace ThemeStoreGraphQl with ThemeStoreGraphQL. Renaming fails in PhpStorm with the prompt: java.io.IOException: 无法将 'E:\wwwroot\object\Modules\ThemeStoreGraphQl'重命名为 ThemeStoreGraphQL
Figure 4

8. Rename it in the operating system directory. See Figure 5.

Rename it in the operating system directory
Figure 5

9. After the batch replacement, run composer install. The error still occurs: Illuminate\Contracts\Container\BindingResolutionException : Target [Modules\ThemeStoreGraphQL\ThemeSetting\Schema\TemplateSchemaLoaderInterface] is not instantiable while building [Modules\ThemeStoreGraphQL\Resolver\OnlineStoreTheme\TemplateSettingsDataResolver].

10. Check /bootstrap/cache/services.php: GraphQlResolverServiceProvider exists in the array key ‘providers’, but not in the array key ‘eager’.

PHP
<?php return array (
  'providers' => 
  array (
    90 => 'Modules\\ThemeStoreDB\\Providers\\ThemeStoreDBServiceProvider',
    91 => 'Modules\\ThemeLocalization\\Providers\\ThemeLocalizationServiceProvider',
    92 => 'Modules\\ThemeAsset\\Providers\\ThemeAssetServiceProvider',
    93 => 'Modules\\ThemeSetting\\Providers\\ThemeSettingServiceProvider',
    94 => 'Modules\\Theme\\Providers\\ThemeServiceProvider',
    95 => 'Modules\\ThemeStoreGraphQL\\Providers\\GraphQlResolverServiceProvider',
  ),
  'eager' => 
  array (
    74 => 'Modules\\ThemeStoreDB\\Providers\\ThemeStoreDBServiceProvider',
    75 => 'Modules\\ThemeLocalization\\Providers\\ThemeLocalizationServiceProvider',
    76 => 'Modules\\ThemeAsset\\Providers\\ThemeAssetServiceProvider',
    77 => 'Modules\\ThemeSetting\\Providers\\ThemeSettingServiceProvider',
    78 => 'Modules\\Theme\\Providers\\ThemeServiceProvider',
  ),
);

11. Edit /Modules/ThemeStoreGraphQL/Providers/GraphQlResolverServiceProvider.php and remove implements DeferrableProvider. After checking /bootstrap/cache/services.php, GraphQlResolverServiceProvider now exists in the array key ‘eager’, and the program runs without errors.

PHP
use Illuminate\Contracts\Support\DeferrableProvider;

class GraphQlResolverServiceProvider extends ServiceProvider implements DeferrableProvider

12. To defer loading a provider, you need to implement the \Illuminate\Contracts\Support\DeferrableProvider interface and provide a provides method. This provides method returns the service container bindings registered by the provider.

PHP
use Illuminate\Contracts\Support\DeferrableProvider;

class GraphQlResolverServiceProvider extends ServiceProvider implements DeferrableProvider
{
    /**
     * 获取由提供者提供的服务。
     *
     * @return array
     */
    public function provides()
    {
        return [TemplateSchemaLoaderInterface::class, TemplateSettingsDataResolver::class, SettingPersisterInterface::class];
    }
}

13. Check /bootstrap/cache/services.php: GraphQlResolverServiceProvider does not exist in the array key ‘eager’, and no error occurs at runtime. See Figure 6.

Check /bootstrap/cache/services.php: GraphQlResolverServiceProvider does not exist in the array key 'eager', and no error occurs at runtime
Figure 6
Plaintext
PS E:\wwwroot\object> php artisan lighthouse:ide-helper
Wrote schema directive definitions to E:\wwwroot\object/schema-directives.graphql.
Wrote definitions for programmatically registered types to E:\wwwroot\object/programmatic-types.graphql.
Wrote PHP definitions to E:\wwwroot\object/_lighthouse_ide_helper.php.

It is recommended to add them to your .gitignore file.

关于作者 · 持续学习与技术实践

我是一名拥有 15 年以上开发经验的技术从业者,自 2013 年起持续运营个人技术博客,记录工作与个人项目中遇到的真实问题,以及解决问题过程中的探索、实践和思考。

除了技术写作,我也在持续开发和维护自己的独立项目,探索新技术和新工具在实际场景中的应用。我始终相信,没有不值得去解决的问题,也没有不值得去学习的技术。

如果这篇文章对你有所帮助,欢迎浏览博客中的其他文章,也欢迎交流技术经验与想法。

关于我  ·  GitHub  ·  邮件联系