Reputation: 1641
I would like to understand how automatic dependancy injection works in laravel. I am using this library https://github.com/yedincisenol/dynamic-links . It has a service provider class which binds to the IoC container
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->app->singleton('DynamicLinks', function ($app) {
return new DynamicLinks($app['config']['dynamic-links']);
});
}
And resolving the class gives me an instance of the library class,
$dynamicLinks = resolve('DynamicLinks');
As per documentaion, the class is auto injected if type hinted in the controller method,
Alternatively, and importantly, you may simply "type-hint" the dependency in the constructor of a class that is resolved by the container, including controllers, event listeners, queue jobs, middleware, and more. In practice, this is how most of your objects should be resolved by the container.
this is my controller method:
public function getLink(Request $request, DynamicLinks $dynamicLinks) {
// other stuffs
}
But the problem is, its not getting the configuaration file in the injected instance and throwing ConfigException
from the library.
This is the constructor for the class
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']
]);
}
It seems that the class is being instanciated without the config instead of using the instance registered by the provider.
Upvotes: 1
Views: 473
Reputation: 2435
This is because the singleton is named 'DynamicLinks'
, which resolves to
DynamicLinks
And the controller method uses the class DynamicLinks
, which resolves to
yedincisenol\DynamicLinks\DynamicLinks
In other words, when you expect it as argument in the controller, the service container tries to find yedincisenol\DynamicLinks\DynamicLinks
, and because it is not registered as a singleton, it just tries to make to construct a new
one.
-
Several solutions:
1)
Instead of having the class as controller argument, resolve it inside it as resolve('DynamicLinks')
2)
In the app/Providers/AppServiceProvider
, in the register method, add:
$this->app->singleton(\yedincisenol\DynamicLinks\DynamicLinks::class, function ($app) {
return resolve('DynamicLinks');
});
3)
fork or send a pull request to the package author to implement something along the lines of 2)
-
So in a nutshell, i recommend going for option 2)
, which should ensure your controller will work as intended.
Upvotes: 2