How to configure Doctrine Entity Manager as a public Symfony service? - php

I'd like to configure Doctrine Entity Manager as a public Symfony service.
I tried adding the following configuration blocks in services.yml (one at a time):
Doctrine\ORM\EntityManagerInterface:
public: true
# [OUTPUT] Error: Cannot instantiate interface Doctrine\ORM\EntityManagerInterface
Doctrine\ORM\EntityManager:
public: true
# [OUTPUT] Invalid service "Doctrine\ORM\EntityManager": its constructor must be public.
doctrine.orm.default_entity_manager:
public: true
# [OUTPUT] The definition for "doctrine.orm.default_entity_manager" has no class. If you intend to inject this service dynamically at runtime, please mark it as synthetic=true. If this is an abstract definition solely used by child definitions, please add abstract=true, otherwise specify a class to get rid of this error.
Judging by the output error messages, I suspect that the definitions are incomplete, but I didn't find anywhere the correct way to manually configure the Doctrine Entity Manager service.

As per Cerad's comment, I had to add alias: 'doctrine.orm.default_entity_manager'
to my first attempted configuration.
So the correct solution is:
Doctrine\ORM\EntityManagerInterface:
public: true
alias: 'doctrine.orm.default_entity_manager'

Related

autowire Predis Interface in symfony

i wanna use ClientInterface in my class constructor and i give an error :
Cannot autowire service "App\Service\DelayReportService": argument "$client" of method "__construct()" references interface "Predis\ClientInterface" but no such service exists. Did you create a class that implements this interface?
seems to be i should add it manually to services.yml i added it like :
Predis\ClientInterface: '#Predis\Client'
and now i give this error:
You have requested a non-existent service "Predis\Client".
what is the solution and why symfony itself dont handle it?
you seem to be confused about how to define a service... which isn't surprising tbh
look here
https://symfony.com/doc/5.4/service_container.html#explicitly-configuring-services-and-arguments
for example
services:
App\Service\Concerns\IDevJobService:
class: App\Tests\Service\TestDevJobService
autowire: true
public: true
where
IDevJobService is an INTERFACE
and
TestDevJobService
is the actual implementation that will be auto injected
using # inside the yaml files is done to reference a service that has already been defined ELSEWHERE
https://symfony.com/doc/5.4/service_container.html#service-parameters
you probably want to watch symfonycasts services tutorial (I am not affiliated and I havent watched it myself yet (sure wish I did)).
EDIT
Predis\Client is a 3rd party class. It isn't in your App namespace or in your src folder. Symfony checks the src folder for class that it will then make to a service. See services.yaml there is a comment there, look for exclude and resource. And I'm not sure, even if you autoload it, that you can then just do #Predis\Client to reference an existing service.
be sure as well to debug your config using
php bin/console debug:autowiring
under linux you could do as well php bin/console debug:autowiring | grep Predis to find it more quickly (if it is there at all)

Symfony 3.4 controller registered as service throws deprecation warning

I have a controller, let's say Acme\ShopBundle\Controller\ProductListController
And its definition in services.yml is as follows:
services:
Acme\ShopBundle\Controller\ProductListController:
class: Acme\ShopBundle\Controller\ProductListController
arguments: ['#product_service']
Which throws this in my log file:
User Deprecated: The "Acme\ShopBundle\Controller\ProductListController" service is private, checking for its existence is deprecated since Symfony 3.2 and will fail in 4.0.
Followed by
User Deprecated: The "Acme\ShopBundle\Controller\ProductListController" service is private, getting it from the container is deprecated since Symfony 3.2 and will fail in 4.0. You should either make the service public, or stop using the container directly and use dependency injection instead.
The stack trace list of files is completely inside vendor/symfony so I'm assuming something is misconfigured, but stumped as to what. Any help appreciated.
Controller service must be public:
services:
Acme\ShopBundle\Controller\ProductListController:
public: true
arguments: ['#product_service']
Why aren't you using autowiring anyway? You could register all of your controllers then:
Acme\ShopBundle\Controller\:
resource: '../src/Acme/ShopBundle/Controller' # mutatis mutandis
tags: ['controller.service_arguments']
Kindly read about new features regarding dependency management in Symfony 3.

Resolving Controller Services in Sylius/Symfony

Hoes does Symfony resolve the Sylius service sylius.controller.shop_user service to the controller class file Sylius\Bundle\UserBundle\Controller\UserController.
My understanding is that sylius.controller.shop_user is a service, and that in Symfony there will be a corresponding service configuration. This service configuration will tell Symfony which class to use when it needs to instantiate the service.
However, I can't seem to find a sylius.controller.shop_user configuration in the Sylius source configuration anywhere. There's just references to this service in routing files
#File: src/Sylius/Bundle/ShopBundle/Resources/config/routing/ajax/user.yml
sylius_shop_ajax_user_check_action:
path: /check
methods: [GET]
defaults:
_controller: sylius.controller.shop_user:showAction
_format: json
_sylius:
repository:
method: findOneByEmail
arguments:
email: $email
serialization_groups: [Secured]
or in on-disk container cache files.
var/cache/dev/srcKernelDevDebugContainer.xml
1798: <parameter key="sylius.controller.shop_user.class">Sylius\Bundle\UserBundle\Controller\UserController</parameter>
15230: <service id="sylius.controller.shop_user" class="Sylius\Bundle\UserBundle\Controller\UserController" public="true">
So how does Symfony know to instantiate the right class for this service?
Is there configuration I'm not seeing? Some Symfony magic that auto-generates the class? Some other mysterious third thing where I don't know what I don't know?
I don't have any specific task in mind, I'm just trying to get a feel for how Sylius and Symfony work under the hood.
The controller service is defined based on ResourceBundle's configuration in Sylius\Bundle\ResourceBundle\DependencyInjection\Driver\AbstractDriver::addController. This driver is called when loading a bundle.
Services with the name sylius.controller.[entity-name] are part of the
Sylius
entity resource system. As best I can tell, when you define your new doctrine entities
in a specific way and
register them as a Sylius resource, Sylius will
automatically generate these controller services based on your
configuration.
The actual line of code that defines these services
is here.
#File: src/Sylius/Bundle/ResourceBundle/DependencyInjection/Driver/AbstractDriver.php
/* ... */
$container->setDefinition($metadata->getServiceId('controller'), $definition);
/* ... */
The
Sylius\Bundle\ResourceBundle\DependencyInjection\Driver\AbstractDriver
class is a (as of 1.3) a base class for the
Sylius\Bundle\ResourceBundle\DependencyInjection\Driver\Doctrine\DoctrineORMDriver
class. How this class ends up being used is by Symfony is unclear, but is
fortunately beyond the scope of this answer.

Symfony service container not overridding child class

I am trying to override a service definition as per https://symfony.com/doc/2.4/components/dependency_injection/parentservices.html#overriding-parent-dependencies
Here are my configs:
//services.yaml
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/{Entity,Migrations,Tests}'
# controllers are imported separately to make sure services can be injected
# as action arguments even if you don't extend any base controller class
App\Controller\:
resource: '../src/Controller'
tags: ['controller.service_arguments']
# add more service definitions when explicit configuration is needed
# please note that last definitions always *replace* previous ones
imports:
- {resource: 'clients.yaml'}
//clients.yaml
services:
App\Api\Client\AbstractClient:
abstract: true
arguments:
- '#serializer'
- '#httplug.client.app'
App\Api\Client\MyClient:
parent: App\Api\Client\AbstractClient
calls:
- [setApiHost, ['%client.api_url%']]
As you can see I have two classes, of which one is an abstract parent.
This appears to be setup correctly (successfully overridden):
Information for Service "App\Api\Client\AbstractClient"
=======================================================
---------------- ------------------------------------------
Option Value
---------------- ------------------------------------------
Service ID App\Api\Client\AbstractClient
Class App\Api\Client\AbstractClient
Tags -
Public yes
Synthetic no
Lazy no
Shared yes
Abstract yes
Autowired no
Autoconfigured no
Arguments Service(serializer)
Service(httplug.client.app.http_methods)
This class says its been autowired & autoconfigured but it has (correctly) inherited the arguments from my AbstractClient, but it has not implemented any setter injection definitions!
Information for Service "App\Api\Client\MyClient"
=========================================================
---------------- ------------------------------------------
Option Value
---------------- ------------------------------------------
Service ID App\Api\Client\MyClient
Class App\Api\Client\MyClient
Tags -
Public no
Synthetic no
Lazy no
Shared yes
Abstract no
Autowired yes
Autoconfigured yes
Arguments Service(serializer)
Service(httplug.client.app.http_methods)
Can someone please guide me as to why my child class is not being correctly overridden?

logging in symfony 2.3

I am trying to write my own messages to the log in Symfony 2.3, from anywhere, and not just the Controller (which I realize you can just do a "$this->get('logger')".
I've seen that in Symfony 1 you can use sfContext, but that class no longer seems to be a viable choice in 2.3.
Any help is appreciated.
Symfony2 has Service-oriented architecture (http://en.wikipedia.org/wiki/Service-oriented_architecture) and logger is one of service (by default Monolog). In controller you have access to service via $this->get('service_name'). Here is more info about service container: http://symfony.com/doc/current/book/service_container.html#what-is-a-service-container. If you wanna use logger in another service you have to define service and inject logger service. Example:
# section with defined service in your config.yml file (by default in config.yml)
services:
# your service name
my_service:
# your class name
class: Fully\Qualified\Loader\Class\Name
# arguments passed to service constructor. In this case #logger
arguments: ["#logger"]
# tags, info: http://symfony.com/doc/current/components/dependency_injection/tags.html
tags:
- { name: monolog.logger, channel: acme }
Additionally you should familiarize with dependency injection docs: http://symfony.com/doc/current/components/dependency_injection/index.html
I hope that helped. If not, please let me know where exactly you want to use logger.

Categories