在 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | 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”)。则不再报错。
1 2 | # "获取主题页面的配置" # templateSettingsData(basename: String!): [ThemeSection] @field(resolver: "Modules\\ThemeStoreGraphQl\\Resolver\\OnlineStoreTheme\\TemplateSettingsDataResolver") |
3、取消注释后,查看 ThemeStoreGraphQl/Resolver/OnlineStoreTheme/TemplateSettingsDataResolver.php 。TemplateSchemaLoaderInterface 被做为构造函数的参数传入。
1 2 3 4 5 6 | private TemplateSchemaLoaderInterface $templateSchemaLoader ; public function __construct(TemplateSchemaLoaderInterface $templateSchemaLoader ) { $this ->templateSchemaLoader = $templateSchemaLoader ; } |
4、查看此模块的服务提供者类,确定是有注册相应的实例的。但是并未执行 register() 。因为未输出 graphql。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | { "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’ 中不存在。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <?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’ 中存在,且程序运行不再报错。
1 2 3 | use Illuminate\Contracts\Support\DeferrableProvider; class GraphQlResolverServiceProvider extends ServiceProvider implements DeferrableProvider |
12、要延迟加载提供者,需要实现 \Illuminate\Contracts\Support\DeferrableProvider 接口并置一个 provides 方法。这个 provides 方法返回该提供者注册的服务容器绑定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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
1 2 3 4 5 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. |
近期评论