I want to pass in the Doctrine Entity Manager so I can access my repositories etc. but I'm having some trouble.
My service is defined:
mlbp_beer.rest.controller:
class: MLBP\BeerBundle\Controller\RestController
arguments:
em: "#doctrine.orm.entity_manager"
This gives me an error:
ParameterNotFoundException: The service "mlbp_beer.rest.controller" has a dependency on a non-existent parameter "doctrine.orm.entity_manager".
Thanks for the help!
That looks right? Make sure rest is defined in your routing.yml like so.. Clear the cache too!
rest:
resource: mlbp_beer.rest.controller
type: rest
Related
I'm working on creating a custom (de)normalizer to handle entities. I have created the normalizer and allowed the service container to autowire/autoconfig. The service is selected correctly during deserialization, but I'm having trouble with the name converter. I want to use the MetadataAwareNameConverter service since I'm using the #SerializedName annotation in my entity. No matter what I do, it is always null in the custom normalizer. I have tried a number of methods of getting the name converter service:
Setting it explicitly in my class constructor
Setting it in the service definition (effectively getting rid of autowire/autoconfig)
Setting MetadataAwareNameConverter as the default in framework.yaml (I discovered it is the default already).
Copied an existing normalizer into my src and renamed it to see if it got the correct name converter (it still didn't work)
Built in normalizers are getting a name converter without issue, it is just my custom normalizer that is having this issue.
Is there anything else I should try? Am I missing a step in setting up my service? Any direction is appreciated.
UPDATE - when I dump the service container, the name converter service is missing from the arguments list
---------------- ----------------------------------------------------------
Option Value
---------------- ----------------------------------------------------------
Service ID App\Normalizer\QNormalizer
Class App\Normalizer\QNormalizer
Tags serializer.normalizer
Public no
Synthetic no
Lazy no
Shared yes
Abstract no
Autowired yes
Autoconfigured yes
Arguments Service(serializer.mapping.class_metadata_factory)
-----THIS IS WHERE THE NAME CONVERTER SHOULD BE----
Service(property_accessor)
Service(property_info)
Service(serializer.mapping.class_discriminator_resolver)
Manually injecting MetadataAwareNameConverter in services.yaml solved problem for me.
App\Serializer\CustomNormalizer:
arguments:
$nameConverter: '#serializer.name_converter.metadata_aware'
I faced same issue.
In my case it was a missconfiguration of services happened because of framework was configured to autoconfigure services (It's default framework configuration).
In result I had my custom normalizer duplicated in list of services.
First one is autoconfigured without priority
Second one is declared by me and having name converter injected:
Service Id
Priority
Class Name
App\Adapter\Symfony\Serializer\Normalizer\TranslationNormalizer
App\Adapter\ApiPlatform\Serializer\Normalizer\ItemNormalizer
api_platform.serializer.normalizer.item
-895
App\Adapter\ApiPlatform\Serializer\Normalizer\ItemNormalizer
Declaration:
api_platform.serializer.normalizer.item:
class: App\Adapter\ApiPlatform\Serializer\Normalizer\ItemNormalizer
arguments:
$nameConverter: '#serializer.name_converter.metadata_aware'
autoconfigure: false
tags:
- {name: serializer.normalizer, priority: -895}
Since autoconfigured normalizer have higher priority in list - it was picked by serializer so my SerializedName annotation wasn't working.
Solution is to disable autoconfiguration for first on service:
App\Adapter\ApiPlatform\Serializer\Normalizer\ItemNormalizer:
autoconfigure: false
I'm working on a light DDD app with Symfony 4. In my services.yaml file, I configured the autowiring as such:
services:
# default configuration for services in *this* file
_defaults:
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
public: false # Allows optimizing the container by removing unused services; this also means
# fetching services directly from the container via $container->get() won't work.
# The best practice is to be explicit about your dependencies anyway.
# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
App\:
resource: '../src/*'
exclude: '../src/{DataFixtures,Migrations,Tests,Domain/IceCream/IceCream.php,Domain/Cake/Cake.php,Domain/Candy/Candy.php}'
I excluded all the entities since they're not services. As you might have noticed, I listed all corresponding files because when I type :
exclude: '../src/{DataFixtures,Migrations,Tests,Domain}'
a runtime exception is raised: Cannot autowire service : "App\Application\Query\Cake\CakesQueryHandler": argument "$cakeRepository" of method "__construct()" references interface "App\Domain\Cake\CakeRepositoryInterface" but no such service exists. You should maybe alias this interface to the existing "App\Infrastructure\Doctrine\Repository\Cake\CakeRepository" service.
The first service, which is a queryhandler, is not autowired.
How can I exclude the whole Domain without having to type all files within it ?
Thank you for your help.
As you said to me directly, the runtime error you have is :
(1/1) RuntimeException
Cannot autowire service "App\Application\Query\Cake\CakesQueryHandler": argument "$cakeRepository" of method "__construct()" references interface "App\Domain\Cake\CakeRepositoryInterface" but no such service exists. You should maybe alias this interface to the existing "App\Infrastructure\Doctrine\Repository\Cake\CakeRepository" service.
In your query handler, you want to inject a service with is typed as App\Domain\Cake\CakeRepositoryInterface.
As a matter of fact, you have declared a service for your category repository with the name : App\Infrastructure\Doctrine\Repository\Cake\CakeRepository.
To fix this, you need to add an alias from your interface to your repository in your services.yaml file :
App\Domain\Cake\CakeRepositoryInterface: '#App\Infrastructure\Doctrine\Repository\Cake\CakeRepository'
I'm developing a bundle and want to set up existed cache service (implements Doctrine\Common\Cache\CacheProvider) to my service. The existed service name will be set up in configuration of bundle:
services:
cache:
class: Doctrine\Common\Cache\FilesystemCache
arguments: ["%kernel.cache_dir%/cache"]
my_bundle:
cache_provider: cache
When I try get this service with $container->get($config['cache_provider']); in MyBundleExtension, I have this error:
The service definition "cache" does not exist.
and calling of $container->has($config['cache_provider']); returns false.
I injects #service_container to my service and gets cache in it - it works. But injecting of container is not good practice.
Do you have any ideas about it?
I have the following service definition for a Doctrine repository in a Symfony project:
my_custom_repository_service:
class: My\Custom\ClassName
factory_service: doctrine.orm.entity_manager
factory_method: getRepository
arguments: [MyCustom:ClassName]
When calling this service like this:
$repository = $this->container->get('my_custom_repository_service')
PhpStorm thinks that $repository is My\Custom\ClassName instead of the Doctrine repository that it actually is. Is it possible to fix this?
You should change the class attribute of your service to Doctrine\ORM\EntityRepository:
my_custom_repository_service:
class: Doctrine\ORM\EntityRepository
factory_service: doctrine.orm.entity_manager
factory_method: getRepository
arguments: [MyCustom:ClassName]
It really doesn't matter in this case since the repository factory will generate an instance of the class you're passing in as an argument (which should also be a subclass of Doctrine\ORM\EntityRepository), but if PHPStorm is picking up on that, this will fix it.
I am defining a new authentication provider and I needed access to the password encoder factory, so I defined my provider as a service and asked for the encoder to be injected. Here is my service definition:
services:
wsse.security.authentication.provider:
class: Fdi\CliperestBundle\Security\Authentication\Provider\WsseProvider
arguments: [#security.encoder_factory,'', %kernel.cache_dir%/security/nonces]
So I was expecting that my provider constructor would get an object of type Symfony\Component\Security\Core\Encoder\EncoderFactory. But I am getting a Symfony\Component\Security\Core\User\ChainUserProvider instead!!
Does anyone know why I am getting this object and what can I do to get the EncoderFactory instead? BTW, I am using FOSUserBundle, donĀ“t know if it has anything to do with this
OK, I found the answer. Since this service is defined as an authentication provider, the first argument to the constructor has to be and user provider which is inserted by the security component. Changing the order of the arguments did the trick:
services:
wsse.security.authentication.provider:
class: Fdi\CliperestBundle\Security\Authentication\Provider\WsseProvider
arguments: ['', %kernel.cache_dir%/security/nonces, #security.encoder_factory]