Description
So Laravel 5.4 removed the ability to use app()->make(MyService::class, ['parameter1', 'parameter2, 'parameter3'])
, yet provides no alternatives to resolve a bound class or interface from the IoC container when we have to pass our own parameters.
A simple example that doesn't work anymore:
// Bind an interface to an implementation in a registered service provider
$this->app->bind(MyServiceInterface::class, function ($app, $parameters) {
return new MyServiceA(...$parameters);
});
// Instantiate whatever class is bound to the interface with the given constructor arguments
$myService = app(MyServiceInterface::class, ['parameter1', 'parameter2', 'parameter3']);
This type of instantiation was useful for a various number of reasons:
- providing default constructor parameters while having the ability to override them (even partially)
- binding interfaces to classes and passing parameters (say
DatabaseRepositoryInterface
with a default returning anEloquentRepository
- simply exchanging the returned class by e.g. a cached class without changing any code throughout your application
- ability to test better
- et cetera
All in all I find it a nice alternative to using new
in some cases. The upgrade docs specify that this is a 'code smell' and thus it has been removed completely. Why exactly and what's the alternative for the above situation? Also, and I know it's a never ending discussion about what to enforce and what to leave to the developer, but why completely remove it given the listed pros?
—
I opened a thread on Laracasts to discuss a possible alternative, but wanted to ping here too about the why and how.