Laravel 5.5无法解决的依赖关系解决

时间:2018-08-17 20:21:20

标签: php laravel laravel-5 dependency-injection

我在进行一些依赖注入时遇到了问题,可以用一只手。我对这一切和Laravel还是陌生的,所以让我知道是否需要更多的清晰度/上下文/代码示例。

错误是这里:

  

Illuminate \ Contracts \ Container \ BindingResolutionException:类App ... \ JWTAuthenticationService中无法解析的依赖项解析[Parameter#0 [iterable $ validators]]

AuthenticationServiceProvider.php

class AuthenticationServiceProvider extends ServiceProvider
{
    private const TAGGED_VALIDATORS = 'jwt_validators';

    public function register()
    {
        $this->app->bind(JWTValidatorInterface::class, function () {
            return new JWTAuthenticationService(
                $this->app->tagged(self::TAGGED_VALIDATORS)
            );
        });

        $this->app->tag(
            [
                ExternalJWTValidator::class,
                ManualJWTValidator::class,
            ],
            self::TAGGED_VALIDATORS
        );
    }
}

JWTAuthenticationService.php

class JWTAuthenticationService implements JWTValidatorInterface
{
    /** @var iterable|JWTValidatorInterface[] */
    private $validators;

    /**
     * @param iterable|JWTValidatorInterface[] $validators
     */
    public function __construct(iterable $validators)
    {
        $this->validators = $validators;
    }

    /**
     * Validate a JWT token.
     *
     * @param string $token
     *
     * @return bool
     */
    public function validate(string $token): bool
    {
        foreach ($this->validators as $validator) {
            dd('Made it to: JWTAuthenticationService');
        }
    }
}

JWTValidatorInterface.php

interface JWTValidatorInterface
{
    /**
     * Validate a JWT token.
     *
     * @param string $token
     *
     * @return bool
     */
    public function validate(string $token): bool;
}

ManualJWTValidator.php

class ManualJWTValidator implements JWTValidatorInterface
{
    /**
     * Validate a JWT token.
     *
     * @param string $token
     *
     * @return bool
     */
    public function validate(string $token): bool
    {
        foreach ($this->validators as $validator) {
            dd('Made it to: ManualJWTValidator');
        }
    }
}

ExternalJWTValidator.php

class ExternalJWTValidator implements JWTValidatorInterface
{
    /**
     * Validate a JWT token.
     *
     * @param string $token
     *
     * @return bool
     */
    public function validate(string $token): bool
    {
        foreach ($this->validators as $validator) {
            dd('Made it to: ManualJWTValidator');
        }
    }
}

完整错误堆栈跟踪: enter image description here

2 个答案:

答案 0 :(得分:1)

我的猜测是,您不能在构造函数中强制使用类型,因为laravel会尝试查找类并解决依赖关系。

因此,基本上,请替换:

public function __construct(iterable $validators)

使用

public function __construct($validators)

如果需要确定,只需检查构造函数内部即可:

if(!is_iterable ($validators)) {
    throw new \Exception('Validator should be iterable!');
}

答案 1 :(得分:0)

我最终放弃了iterable类型的提示,并将服务提供商更改为使用splat operator。像我需要的那样工作。

$this->app->bind(JWTValidatorInterface::class, function () {
    $validators = $this->app->tagged(self::TAGGED_VALIDATORS);

    return new JWTAuthenticationService(...$validators);
});