So I figured I'd try to actually use this fancy IoC container in Laravel. I'm starting with Guzzle but I cannot get it to work. Perhaps there is a gap in my understanding. I really appreciate any help here.
so I've got a class for connecting to a RESTful Api. Here is a sample from it:
use GuzzleHttp\Exception\BadResponseException;
use GuzzleHttp\Client;
use GuzzleHttp\Subscriber\Oauth\Oauth1;
class EtApi {
//you can pass in the model if you wanna
//protected $model;
//client Id
protected $clientId;
//client secret
protected $clientSecret;
//base_uri
protected $getTokenUri;
protected $client;
//build
function __construct(Client $client)
{
$this->client = $client;
$this->clientId = 's0m3R4nd0mStr1nG';
$this->clientSecret = 's0m3R4nd0mStr1nG';
$this->getTokenUri = 'https://rest.api/requestToken';
$this->accessToken = $this->getToken($this->clientId, $this->clientSecret, $this->getTokenUri);
}
}
I've successfully installed and used Guzzle by manually newing it up inside of methods like $client = new Client(); but that's not very DRY and it's not the right way of doing things. So I created a ServiceProvider at app\Providers\GuzzleProvider.php. I made sure this was registered in app/config/app.php under $providers = ['App\Providers\GuzzleProvider']
. Here is the Provider Code:
<?php namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use GuzzleHttp\Client;
use GuzzleHttp\Subscriber\Oauth\Oauth1;
class GuzzleProvider extends ServiceProvider {
/**
* Bootstrap the application services.
*
* @return void
*/
public function boot()
{
//
}
/**
* Register the application services.
*
* @return void
*/
public function register()
{
//
$this->app->bind('Client', function () {
return new Client;
});
}
}
So when I try to access my EtApi methods that load fails during the instantiation (__construct) with the following error.
ErrorException in EtApi.php line 23:
Argument 1 passed to App\EtApi::__construct() must be an instance of GuzzleHttp\Client, none given, called in /home/vagrant/webdocs/et_restful_test/app/Http/Controllers/EtConnectController.php on line 23 and defined
Do any of you Laravel Masters have any idea why I can't bind Guzzle using this code and Laravel's magic will just inject the obj into the constructor? The [docs1 say I should be able to do this. I must be missing something. Thank You!
It's a little hard to say for certain based on the information in your question, but based on this
Argument 1 passed to App\EtApi::__construct() must be an instance of GuzzleHttp\Client, none given, called in /home/vagrant/webdocs/et_restful_test/app/Http/Controllers/EtConnectController.php on line 23 and defined
It sounds like you're directly instantiating your App\Eti
class on line 23 of EtConnectController.php
with code that looks something like this
$api = new App\EtApi;
If that's the case, there's a key piece of Laravel's dependency injection you're missing. Laravel can't change the behavior of standard PHP -- i.e. if you create a new class with PHP's built-in new
keyword, then Laravel never has the change to inject any dependencies in __construct
.
If you want to take advantage of dependency injection, you also need to instantiate your object via Laravel's app container. There's many different way to do that -- here's two them
//$api = new App\EtApi;
\App::make('App\EtApi'); //probably "the right" way
$api = app()['App\EtApi']
If you do that, Laravel will read the type hints in __construct
and try to inject dependencies for your object.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With