shuba.ivan
shuba.ivan

Reputation: 4061

Symfony 3.3.5 config service

I have some class ObjectManager and want create service for him, I create config

services:
_defaults:
    autowire: true
    autoconfigure: true
    public: false

AppBundle\:
    resource: '../../src/AppBundle/*'
    exclude: '../../src/AppBundle/{Entity,Repository,Tests}'

AppBundle\Service\:
    resource: '../../src/AppBundle/Service'
    public: true

app.object_manager:
    class: AppBundle\Service\ObjectManager
    arguments:
        - '@jms_serializer'
        - '@validator'

and after get this service in controller and have error

$objectManager = $this->get('app.object_manager');

You have requested a non-existent service "app.object_manager".

Why this happened, symfony 3.3.5 have different way for config services ?

Upvotes: 0

Views: 180

Answers (3)

Tomas Votruba
Tomas Votruba

Reputation: 24280

You can actually use Symfony 3.3+ to it's full potential.

If I understand you correctly, you need to get AppBundle\Service\ObjectManager to your Controller.

In that case...

1. Modify your services.yml

services:
    _defaults:
        autowire: true

    AppBundle\:
        resource: '../../src/AppBundle/*'
        exclude: '../../src/AppBundle/{Entity,Repository,Tests}'

2. Require AppBundle\Service\ObjectManager via constructor (anywhere you need it)

use AppBundle\Service\ObjectManager;

final class MyController
{
    /**
     * @var ObjectManager
     */
    private $objectManager;

    public function __construct(ObjectManager $objectManager)
    {
        $this->objectManager = $objectManager;
    }

    public function someAction()        
    {
        $this->objectManager->someCoolMethod();
    }
}

That's all!

Nothing fancy, just pure Symfony awesomes!

Upvotes: 0

user6461028
user6461028

Reputation:

First of all, when you want to be able to call a service with get, you have to define it public.

app.object_manager:
    class: AppBundle\Service\ObjectManager
    public: true

But you can do that also in top of the services.yml, to define, that all services are public:

services:
    _defaults:
        autowire: true
        autoconfigure: true
        public: true

That way, you don't have to do it explicitly at every service.

Furthermore, I would recommend you, to use the new autowiring feature of Symfony. That way, you do not have to define a service in the services.yml.

Just define the constructor in your ObjectManager class like that:

class ObjectManager
{
    private $jms_serializer;
    private $validator;

    public function __construct(SerializerInterface $jms_serializer, ValidatorInterface $validator)
    {
        $this->jms_serializer   = $jms_serializer;
        $this->validator        = $validator;
    }
}

He will find the correct services by autowiring then. And you do not have to define anything in the services.yml.

So, to sum up your services.yml should just contain the following:

services:
    _defaults:
        autowire: true
        autoconfigure: true
        public: true

AppBundle\:
    resource: '../../src/AppBundle/*'
    exclude: '../../src/AppBundle/{Entity,Repository,Tests}'

Upvotes: 1

genesst
genesst

Reputation: 1431

Looks like you need to explicitly define your services as public since Symfony 3 if you want to use them through get().

# app/config/services.yml
services:
    # default configuration for services in *this* file
    _defaults:
        # ...
        public: false

More info here - http://symfony.com/doc/current/service_container.html#public-versus-private-services

Upvotes: 0

Related Questions