I am using Laravel Framework 5.8.21
. I am trying to bind an interface
to a class based on Request
params inside AppServiceProvider
's register
method like this.
public function register()
{
$this->app->bind('App\Contracts\SomeInterface', 'App\Logic\ClassName');
if(Request::has('notification_type') && Request::get('notification_type') == 'email') {
$this->app->bind('App\Contracts\SomeInterface', 'App\Logic\SomeotherClassName');
}
}
and later injecting the interface to Controller
s __construct()
method.
with tests, it always bound to ClassName
. I tried to get accessed URL inside AppServiceProvider
and while running unit tests
, it always returning /
with $this->app->request->getRequestUri();
and method as GET
even though from the test I am posting to URL like this.
$this->post('/notification', [
'notification_type' => 'email',
])->assertJson(
'message-push-status' => true,
]);
While testing it with Postman, when I try to post http://localhost:8000/notification
, it says, 419 | Page Expired.
You will not be able to reliably use the current request information from within a service provider.
First, it is a general best practice to not depend on application logic within the register()
method directly. You may cause a race condition where you have a dependency that hasn't been registered yet, or cause unnecessary overhead (e.g. establish a database connection even if you don't need any querying).
Second, Laravel's request lifecycle won't funnel the current request into the application until after all of the service provider registration and bootstrapping has been completed.
Without knowing exactly what business logic you're trying to accomplish, you have at least a couple options:
Use contextual binding to serve different implementations of the same interface depending on the requesting object (e.g. controller).
Use a factory or a similar facilitator-style object that you can inject in the controller, and can provide the proper dependency based on your preferred logic.