As far as I've understood, I should be able to type-hint my class instance arguments in the constructor of my class that I only instantiate with help of a Service Provider. Unfortunately I'm getting an error about missing arguments.
Tracker.php
function __construct($query, Tracker\Shipment $shipment) {
$this->query = $query;
$this->shipment = $shipment;
}
TrackerServiceProvider.php
class TrackerServiceProvider extends \Illuminate\Support\ServiceProvider {
public function register() {
$this->app->bind('TrackerAPI', function($app, $shipment_number) {
return new Tracker\API($shipment_number); // omitting Shipment argument should resolve on its own?
});
}
}
Class API is extending Tracker, thus using its constructor. Why isn't it resolving without the implied class type hint?
You've confused the PHP new
functionality with Laravel's dependency injection via type hinting functionality.
In your TrackerAPI
binding, when you specify return new Tracker\API($shipment_number);
, there is nothing built into PHP to try to flesh out any missing parameters. To do this, you would need to return $app->make('Tracker\API', [$shipment_number]);
When you use the App::make()
method, Laravel will do its magic to create a new object. It first checks for an explicitly defined binding. If it doesn't find an explicit binding, it will fall back to just using a combination of the supplied parameters plus type hints to create objects for any missing parameters.
Take the following statement: App::make('Tracker\API', [$shipment_number])
. Assume there is no explicitly defined binding for Tracker\API
. The Tracker\API
constructor requires two parameters. $shipment_number
is passed in in the parameter array, so it will be used as the first parameter. Since only one parameter was supplied, Laravel will App::make()
the rest of the parameters using the type hints.
However, when you specifically instantiate the object yourself using the new
keyword, none of this happens. It is a plain PHP object instantiation.
Nope. Laravel can't resolve partials like that. You have to be explicit:
use Tracker\API;
use Tracker\Shipment;
use Illuminate\Support\ServiceProvider;
class TrackerServiceProvider extends ServiceProvider {
public function register()
{
$this->app->bind('TrackerAPI', function($app, $shipment_number)
{
return new API($shipment_number, $app[Shipment::class]);
});
}
}
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