Symfony 4 container array service parameter - php

In file service.yaml i have:
parameters:
security.allows.ip:
- '127.0.0.1'
- '127.0.0.2'
Or:
parameters:
security.allows.ip: ['127.0.0.1', '127.0.0.2']
And configuration for DI:
services:
_defaults:
autowire: true
autoconfigure: true
public: false
And i want to configure service for class:
security.class:
class: App\Class
arguments:
- '%security.allows.ip%'
And finally I have message:
Cannot autowire service "App\Class": argument "$securityConfiguration" of method "__construct()" must have a type-hint or be given a value explicitly.
And constructor definition is:
public function __construct(array $securityConfiguration)
Could you help me with it? In symfony 2.8 it works, but for this configuration I have this error. Other sevices for type hint string is ok, but not for this class. If I add container interface to construct for this class and getting parameter by ->getParameter('security.allows.ip') it works. Why?

In order for autowire to work, the typehint need to match a service id. The problem here is that you have another class into which you are trying to inject your rather poorly named App\Class
class SomeOtherClass {
public function __construct(App\Class $appClass)
When you created your AppClass service, you gave it an id of security.class. So autowire looks for a service id of App\Class, does not find it and then attempts to create one. And of course it cannot autowire an array.
One way to fix this is by using an alias:
security.class:
class: App\Class
arguments:
- '%security.allows.ip%'
App\Class: '#security.class'
A second (recommended) approach is to do away with the security.class id completely
App\Class:
arguments:
- '%security.allows.ip%'
And if you really want to be the cool kid on the block, you can even drop the arguments keyword.
App\Class:
$securityConfiguration: '%security.allows.ip%'

Related

Symfony 6 - cannot resolve argument

I've created a class App\Service\Steam\SteamAPIRepository and it is listed when I run bin/console debug:container. My class constructor looks like this:
public function __construct(HttpClientInterface $httpClient, CacheInterface $cache, string $apiKey)
{
$this->setCache($cache);
$this->setHttpClient($httpClient);
$this->setApiKey($apiKey);
$this->setSteamUrl('http://api.steampowered.com/');
}
Before I added the $apiKey argument (and just had it hardcoded in the constructor), this was working fine and could be autowired in a controller method for example. I added the API key argument and inside config/services.yaml I did the following:
parameters:
steam.apiKey: 'myapikey'
services:
# after _defaults and App
App\Service\Steam\SteamAPIRepository\:
resource: '../src/Service/Steam/SteamAPIRepository.php'
bind:
$apiKey: '%steam.apiKey%'
But now I see the error:
Cannot resolve argument $steamAPIRepository of "App\Controller\App\IndexController::index()":
Cannot autowire service "App\Service\Steam\SteamAPIRepository":
argument "$apiKey" of method "__construct()" is type-hinted "string",
you should configure its value explicitly.
Any ideas where I'm going wrong?
I figured this out, I was making quite a simple mistake inside config/services.yaml. I replaced:
App\Service\Steam\SteamAPIRepository\:
resource: '../src/Service/Steam/SteamAPIRepository.php'
bind:
$apiKey: '%steam.apiKey%'
with:
App\Service\Steam\SteamAPIRepository:
arguments:
$apiKey: '%steam.apiKey%'
Now this works as intended

Reference Tagged Services cannot be resolved

I try configure my services in Symfony 5.5 with tags and a resource folder and I also used some different notations. Either I got an empty iterator as constructor param or the exception "Cannot autowire service ... argument "..." of method "__construct()" is type-hinted "iterable", you should configure its value explicitly.".
I used that easy feature in previous versions and I followed that instruction: https://symfony.com/doc/current/service_container/tags.html#reference-tagged-services.
Here that related part of my services.yaml:
services:
_defaults:
autowire: true
autoconfigure: true
App\Service\LinkTypeGuesser\:
resource: '../src/Service/LinkTypeGuesser'
tags: ['link.type.guesser']
App\Service\LinkTypeGuesser:
arguments:
- !tagged_iterator link.type.guesser
My "parent" service class constructor looks like that:
class LinkTypeGuesser
{
private $guessers;
public function __construct(iterable $linkTypeGuessers)
{
$this->guessers = $linkTypeGuessers;
}
}
Any hints what I missed in my configuration?
I don't really know your repository therefor the file system.
First of all the argument resource is not supported.
Supported arguments are "shared", "lazy", "public", "properties", "configurator", "calls", "tags", "autowire", "bind"
resource: '../src/Service/LinkTypeGuesser'
Symfony will find your resources based on the Fully Qualified Namespace, you have set as an key. This means everything that implements or extends this Service will be tagged.
You want to add a custom tag and inject all services in your parent service.
You have a syntax error, the argument _instanceof is missing.
GO ahead and try this code (Please change whitespaces to match yaml format):
services:
_defaults:
autowire: true
autoconfigure: true
_instanceof:
App\Service\LinkTypeGuesser:
tags: ['link.type.guesser']
App\Service\LinkTypeGuesser:
arguments:
- !tagged_iterator link.type.guesser

Symfony 3.4 - Auto wire of service not working in method

I'm relatively new to Symfony, and I'm having trouble some trouble.
I'm trying to type hint a custom RequestValidator class in the method being called when the endpoint is called.
Using Symfony 3.4
However, I am getting the following error:
Controller "ApiBundle\Endpoints\Healthcheck\v1\Index::check()" requires that you provide a value for the "$request" argument. Either the argument is nullable and no null value has been provided, no default value has been provided or because there is a non optional argument after this one.
Here is my setup:
services.yml file
...
_defaults:
autowire: true
autoconfigure: true
...
routing.yml
api.Healthcheck:
path: /healthcheck
controller: ApiBundle\Endpoints\Healthcheck\v1\Index::check
defaults: { _format: json }
methods:
- GET
And then - inside the Index class, I have the following:
<?php
namespace ApiBundle\Endpoints\Healthcheck\v1;
use ApiBundle\Responses\ApiResponse;
class Index extends ApiResponse
{
public function check(HealthcheckRequest $request) {
var_dump($request);die;
}
}
When I do debug:autowiring I see my HealthcheckRequest in the list.
Further, when I do the same and try type-hint in the constructor of the Index class, it all works.
And finally, if I try and type hint the Symfony/HttpFoundation/Request, inside the check() method, it instantiates it correctly.
In summary:
Not working :
check(HealthcheckRequest $request)
Working:
__construct(HealtcheckRequest $request)
check(SymfonyRequest $request)
Am I doing something wrong? Any help is appreciated.
It's part of services.yaml already in Symfony 4, but introduced in version 3.3, so this might help:
# controllers are imported separately to make sure services can be injected
# as action arguments even if you don't extend any base controller class
ApiBundle\Endpoints\:
resource: '../../Endpoints/*'
tags: ['controller.service_arguments']

Symfony service declaration in services.yml

I am writing a service in Symfony 3 according to latest docs.
I wrote a class:
<?php
namespace julew\AdminBundle\Service;
class FileService {
public function create() {
die('I am here!');
}
}
My app/config/services.yml looks like:
services:
# default configuration for services in *this* file
_defaults:
# automatically injects dependencies in your services
autowire: true
# automatically registers your services as commands, event subscribers, etc.
autoconfigure: true
# this means you cannot fetch services directly from the container via $container->get()
# if you need to do this, you can override this setting on individual services
public: false
julew\AdminBundle\:
resource: '../../src/julew/AdminBundle/*'
exclude: '../../src/julew/AdminBundle/{Entity,Repository}'
But only what i get is this error:
Class Symfony\Bundle\FrameworkBundle\Test\WebTestCase not found in C:\xampp\htdocs\roch\app/config\services.yml (which is being imported from "C:\xampp\htdocs\roch\app/config\config.yml").
What am i doing wrong?
EDIT 1
The problem was, that automatically generated bundles had tests in it - had to add them to exclude paths.
But now other problem occured. Service is not injected via controler type-hint. Error that i get:
Controller "julew\RochNotesBundle\Controller\ParserController::indexAction()" requires that you provide a value for the "$fileService" argument. Either the argument is nullable and no null value has been provided, no default value has been provided or because there is a non optional argument after this one.
The controller method looks like:
public function indexAction(FileService $fileService) {
.
.
.
}
And at the top i added:
use julew\AdminBundle\Service\FileService;
If you want to inject various services into a controller, it can be a little easier to do so in the constructor, and avoid the use of the controller.service_arguments tag (which has to be explicitly added for the controller definition in the services.yml).

Override translator class not working in symfony3

I need to know how to override the trans method in symfony3.
In symfony2 project we used to override the parameter for the translator class
parameters:
translator.class: Acme\HelloBundle\Translation\Translator
We started using symfony3 and try to apply the same approach but unfortunately the parameter was removed and the class path is written directly into the service.
You can override an existing definition (e.g. when applying the Decorator pattern). This kind of decoration is supported by the Dependency Injection Container of Symfony as described in the doc. As example:
services:
app.mailer:
class: AppBundle\Mailer
# this replaces the old app.mailer definition with the new one, the
# old definition is lost
app.mailer:
class: AppBundle\DecoratingMailer
and:
services:
# ...
app.decorating_mailer:
class: AppBundle\DecoratingMailer
decorates: app.mailer
arguments: ['#app.decorating_mailer.inner']
public: false
Hope this help

Categories