在 Laravel 6、Lighthouse 5、nwidart/laravel-modules 7 中,报错:Illuminate\Contracts\Container\BindingResolutionException : Target [Interface] is not instantiable while building [Resolver]. 要延迟加载提供者,未实现 provides 方法所导致
1、在 Lighthouse 5 中,报错:Illuminate\Contracts\Container\BindingResolutionException : Target [Interface] is not instantiable while building [Resolver].。如图1
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、编辑 ThemeStoreGraphQl/Resources/graphql/theme_setting.graphql ,注释掉:templateSettingsData(basename: String!): [ThemeSection] @field(resolver: “Modules\\ThemeStoreGraphQl\\Resolver\\OnlineStoreTheme\\TemplateSettingsDataResolver”)。则不再报错。
# "获取主题页面的配置" # templateSettingsData(basename: String!): [ThemeSection] @field(resolver: "Modules\\ThemeStoreGraphQl\\Resolver\\OnlineStoreTheme\\TemplateSettingsDataResolver")
3、取消注释后,查看 ThemeStoreGraphQl/Resolver/OnlineStoreTheme/TemplateSettingsDataResolver.php 。TemplateSchemaLoaderInterface 被做为构造函数的参数传入。
private TemplateSchemaLoaderInterface $templateSchemaLoader; public function __construct(TemplateSchemaLoaderInterface $templateSchemaLoader) { $this->templateSchemaLoader = $templateSchemaLoader; }
4、查看此模块的服务提供者类,确定是有注册相应的实例的。但是并未执行 register() 。因为未输出 graphql。
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、查看模块列表,其 Name 为 ThemeStoreGraphQL,Path 为 E:\wwwroot\object\Modules/ThemeStoreGraphQl。如图2
6、查看 /Modules/ThemeStoreGraphQl/composer.json,其路径 ThemeStoreGraphQL 与实际目录名 ThemeStoreGraphQl 不匹配。调整为与实际目录名一致。如图3
{ "extra": { "laravel": { "providers": [ "Modules\\ThemeStoreGraphQL\\Providers\\GraphQlResolverServiceProvider" ], "aliases": { } } }, "autoload": { "psr-4": { "Modules\\ThemeStoreGraphQL\\": "" } } }
7、重命名目录名为:ThemeStoreGraphQL,然后批量替换 ThemeStoreGraphQl 为 ThemeStoreGraphQL。在 PhpStorm 中重命名失败,提示:java.io.IOException: 无法将 ‘E:\wwwroot\object\Modules\ThemeStoreGraphQl’重命名为 ThemeStoreGraphQL。如图4
8、在操作系统目录中重命名。如图5
9、批量替换后,执行 composer install。仍然报错:Illuminate\Contracts\Container\BindingResolutionException : Target [Modules\ThemeStoreGraphQL\ThemeSetting\Schema\TemplateSchemaLoaderInterface] is not instantiable while building [Modules\ThemeStoreGraphQL\Resolver\OnlineStoreTheme\TemplateSettingsDataResolver].
10、查看 /bootstrap/cache/services.php,GraphQlResolverServiceProvider 在数组键 ‘providers’ 中存在,在数组键 ‘eager’ 中不存在。
<?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、编辑 /Modules/ThemeStoreGraphQL/Providers/GraphQlResolverServiceProvider.php,删除掉 implements DeferrableProvider 后,查看 /bootstrap/cache/services.php 的 GraphQlResolverServiceProvider 在数组键 ‘eager’ 中存在,且程序运行不再报错。
use Illuminate\Contracts\Support\DeferrableProvider; class GraphQlResolverServiceProvider extends ServiceProvider implements DeferrableProvider
12、要延迟加载提供者,需要实现 \Illuminate\Contracts\Support\DeferrableProvider 接口并置一个 provides 方法。这个 provides 方法返回该提供者注册的服务容器绑定
use Illuminate\Contracts\Support\DeferrableProvider; class GraphQlResolverServiceProvider extends ServiceProvider implements DeferrableProvider { /** * 获取由提供者提供的服务。 * * @return array */ public function provides() { return [TemplateSchemaLoaderInterface::class, TemplateSettingsDataResolver::class, SettingPersisterInterface::class]; } }
13、查看 /bootstrap/cache/services.php 的 GraphQlResolverServiceProvider 在数组键 ‘eager’ 中不存在,运行时不再报错。如图6
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.
近期评论