Reputation: 894
I'm having an issue with some dependency injection and could use a hand. I'm new to all this and Laravel so let me know if you need more clarity/context/code examples.
The error is get is thise:
Illuminate\Contracts\Container\BindingResolutionException: Unresolvable dependency resolving [Parameter #0 [ iterable $validators ]] in class App...\JWTAuthenticationService
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');
}
}
}
Upvotes: 0
Views: 2788
Reputation: 894
I ended up abandoning the iterable
type hinting and changed up the service provider to use the splat operator. Worked like i needed.
$this->app->bind(JWTValidatorInterface::class, function () {
$validators = $this->app->tagged(self::TAGGED_VALIDATORS);
return new JWTAuthenticationService(...$validators);
});
Upvotes: 0
Reputation: 15131
My guess is that you can't enforce the type in your constructor, because laravel will try to find a class and resolve the dependency.
So, basically, replace:
public function __construct(iterable $validators)
With
public function __construct($validators)
In case you need to be sure, just check inside the constructor:
if(!is_iterable ($validators)) {
throw new \Exception('Validator should be iterable!');
}
Upvotes: 1