Search code examples
phplaravelioc-containermiddleware

Laravel Dependency Injection in Middleware


I am using Laravel-5.0's default Authentication Middleware, but I changed the signature of the handle function to have:

public function handle($request, Closure $next, AuthClientInterface $authClient)

I also registered AuthClientInterface in a Service Provider with:

public function register()
{
    $this->app->bind('App\Services\Contracts\AuthClientInterface', function()
    {
        return new AuthClient(
            env('AUTH_SERVER_URL'),
            env('AUTH_SESSION_URL'),
            env('AUTH_CLIENT_ID')
        );
    });
}

However, despite this, I am see the following error:

Argument 3 passed to HelioQuote\Http\Middleware\Authenticate::handle() 
must be an instance of 
HelioQuote\Services\Contracts\HelioAuthClientInterface, none given, 
called in C:\MyApp\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php on line 125 and defined...

Can anyone see what I am doing wrong?

EDIT: I did get it working by passing the HelioAuthClientInterface into the constructor of the middleware. However I thought the IoC container would also inject the dependency to methods in addition to the constructor.


Solution

  • You cannot do dependency injection at handle method in a Request directly, do that in a constructor.

    Middleware is invoked by call_user_func, so any injection here will not be work.

    <?php
    
    namespace App\Http\Middleware;
    
    use Closure;
    use App\Foo\Bar\AuthClientInterface; # Change this package name
    
    class FooMiddleware
    {
      protected $authClient;
    
      public function __construct(AuthClientInterface $authClient)
      {
        $this->authClient = $authClient;
      }
    
      public function handle(Request $request, Closure $next)
      {
        // do what you want here through $this->authClient
      }
    }