Reputation: 25945
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?
Upvotes: 6
Views: 4785
Reputation: 62228
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.
Upvotes: 9
Reputation: 219930
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]);
});
}
}
Upvotes: 2