2016-02-16 4 views
4

Я использую Laravel-5.0 по умолчанию Authentication Middleware, но я изменил подпись функции ручки иметь:Laravel Dependency Injection в Middleware

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

Я также зарегистрировал AuthClientInterface в поставщика услуг с:

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') 
     ); 
    }); 
} 

Однако, несмотря на это, я вижу следующее сообщение об ошибке:

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... 

Может ли кто-нибудь увидеть, что я делаю неправильно?

EDIT: Я получил его, передав HelioAuthClientInterface в конструктор промежуточного программного обеспечения. Однако я думал, что контейнер IoC также будет добавлять зависимость к методам в дополнение к конструктору.

ответ

13

Вы не можете выполнить инъекцию зависимостей в методе handle в запросе напрямую, сделайте это в конструкторе.

Middleware вызывается call_user_func, поэтому любая инъекция здесь не будет работать.

<?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 
    } 
} 
+0

OP может использовать контейнер IoC для разрешения реализации из абстракции. App :: make() - ваш друг в этом случае. – Burimi

+0

@Burimi это довольно сложно, я думаю, что использование функций конструкции достаточно ясно для этого использования – tucq88

3

IoC обрабатывает метод конструктора только для всех объектов по умолчанию. IoC будет только вводить зависимости в функции , обрабатываемые маршрутизатором. Это может быть закрытие, используемое для обработки маршрута или, чаще, методы контроллера, используемые для обработки маршрутов.

IOC не выполняет метод инъекции зависимостей для любого другого объекта по умолчанию. Вы можете вызывать методы самостоятельно через IoC и разрешать зависимости, но инфраструктура делает это только для обработчиков маршрутов. Вы можете взглянуть на этот вопрос/ответ для получения дополнительной информации об использовании инъекции зависимостей метода за пределами контроллера: can I use method dependency injection outside of a controller?.

Обращение с этим путем ввода вашей зависимости через конструктор - это правильный путь, если вы хотите продолжать использовать инъекцию зависимостей.

2

Здесь вы не можете изменить подпись метода. Просто вы можете использовать что-то вроде этого:

public function handle($request, Closure $next) { 

    // Get the bound object to this interface from Service Provider 
    $authClient = app('App\Services\Contracts\AuthClientInterface'); 

    // Now you can use the $authClient 
} 

Кроме того, вы можете использовать метод __construct, чтобы добиться того, чтобы проверить ответ дается - Francis.TM.