我想了解laravel中自动依赖注入的工作原理。我正在使用这个库https://github.com/yedincisenol/dynamic-links。它具有绑定到IoC容器的服务提供商类
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->app->singleton('DynamicLinks', function ($app) {
return new DynamicLinks($app['config']['dynamic-links']);
});
}
解析该类会给我一个库类的实例,
$dynamicLinks = resolve('DynamicLinks');
根据文档,如果控制器方法中提示了类型,则自动注入该类
或者,重要的是,您可以简单地“键入提示” 类的构造函数中的依赖项,由 容器,包括控制器,事件监听器,队列作业, 中间件等。实际上,这就是您大多数对象的方式 应该由容器来解决。
这是我的控制器方法:
public function getLink(Request $request, DynamicLinks $dynamicLinks) {
// other stuffs
}
但是问题是,它没有在注入的实例中获取配置文件,而没有从库中抛出ConfigException
。
这是该类的构造函数
public function __construct(array $config = null)
{
if ($config == null) {
$config = require_once 'config.php';
}
if ($config == null || !isset($config['api_key']) || strlen($config['api_key']) < 1) {
throw new ConfigException;
}
$this->config = $config;
$this->client = new Client([
'base_uri' => 'https://firebasedynamiclinks.googleapis.com/v1/shortLinks?key=' . $config['api_key']
]);
}
似乎在没有配置的情况下实例化了该类,而不是使用提供者注册的实例。
答案 0 :(得分:2)
这是因为单例名为'DynamicLinks'
,其解析为
DynamicLinks
并且控制器方法使用类DynamicLinks
,该类解析为
yedincisenol\DynamicLinks\DynamicLinks
换句话说,当您期望它作为控制器中的参数时,服务容器会尝试找到yedincisenol\DynamicLinks\DynamicLinks
,并且由于它没有注册为单例,因此它只是试图构造一个{{1 }}一。
-
几种解决方案:
1)
与其将类用作控制器参数,不如将其解析为new
2)
在resolve('DynamicLinks')
的register方法中,添加:
app/Providers/AppServiceProvider
3)
fork或向软件包作者发送拉取请求,以按照$this->app->singleton(\yedincisenol\DynamicLinks\DynamicLinks::class, function ($app) {
return resolve('DynamicLinks');
});
-
因此,简而言之,我建议您使用选项2)
,该选项应确保您的控制器可以按预期工作。