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?