1

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.

2
  • or the configuration is returning null ... also what does your class reference DynamicLinks point to in your controller method? Commented Jul 24, 2018 at 7:19
  • @lagbox, the class reference is the yedincisenol\DynamicLinks\DynamicLinks; class in the library. Thats why $config is null. Commented Jul 24, 2018 at 7:34

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

8 Comments

can also alias the binding to the FQCN
@lagbox true, but i forgot the exact syntax for it, so instead i shared code that i 100% know will work 😇
$this->app->alias('DynamicLinks', DynamicLinks::class)
@lagbox good to know, its present in the code but not on the documentation page 🎁
understood. Thanks a lot for your time. both of you. :)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.