Avoid long lists of arguments in constructor service Symfony

Viewed 1045

I've been using Symfony to develop my web applications but I keep running into one problem. I always end up with too much clutter in the constructor of my services since I want to be able to unit test my services properly.

Theoretical use case

Let's say I need a service which allows me to process an XML file and save it's contents into the database.

<?xml version="1.0" encoding="UTF-8" ?>
<users>
    <user>
        <id>1234</id>
        <username>Example User</username>
        <email>user@example.com</email>
        <usergroup>
            <id>567</id>
            <name>Example User Group</name>
        </usergroup>
        <permissions>
            <item>ALLOWED_TO_CREATE</item>
            <item>ALLOWED_TO_UPDATE</item>
            <item>ALLOWED_TO_DELETE</item>
            <item>ALLOWED_TO_view</item>
        </permissions>
    </user>
</users>

Already quite a few things come to mind which you need to inject into this service:

  • DomCrawler (to read the XML file)
  • UserRepository (to get existing Users)
  • UserGroupRepository (to get existing UserGroups)
  • PermissionsRepository (to get existing permissions)
  • EntityManager (to persist en flush new/updated objects)

The real XML file I'm working with contains much more data which requires me to inject many more repositories and other services which handle certain logic.

Solution 1: Use Doctrine service

Inject the Doctrine service directory into my service and get the repositories via $doctrine->getRepository(User::class)

Pros

  • Significatly reduces the amount of arguments

Cons

  • Unit testing becomes a lot harder since I don't know what the service accesses anymore which renders them useless

Solution 2: Use setter injection

Remove all services and repositories from the constructor and create setter methods and call then in the services.yml

services:
  AppBundle\Service\MyImportService:
    calls:
      - [setUserRepository, ['@app.user_repository']]

Pros

  • Arguably easier to read

Cons

  • More code
  • Services no longer mandatory, optional validation may be required

Question

What are solutions to make the argument lists in my services more maintainable in terms of readability and ability to unit test?

Is it even considered bad practise to have a long list of arguments?

1 Answers
Related