在 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.
![在 Lighthouse 5 中,报错:Illuminate\Contracts\Container\BindingResolutionException : Target [Interface] is not instantiable while building [Resolver].](https://www.shuijingwanwq.com/wp-content/uploads/2022/06/1-17.png)





近期评论