Normally when I need to inject one or more services into another service, I explicitly inject each one. However, I have a situation where injecting the service container itself will really make things easier. I know this is not a recommended practice, but I'm curious what the technical reasons are for discouraging this. Is it something legitimate like it's too resource intensive, or a more personal feeling that it's too messy?
A Service Container (or dependency injection container) is simply a PHP object that manages the instantiation of services (i.e. objects).
Dependency injection helps to develop testable code, allowing developers to write unit tests easily. You can use mock databases with dependency injection, and test your application without affecting the actual database.
A basic benefit of dependency injection is decreased coupling between classes and their dependencies. By removing a client's knowledge of how its dependencies are implemented, programs become more reusable, testable and maintainable.
If you inject the container, you're not making dependencies clear. In fact, you're obscuring them more than before. If you have a class like this...
class DocumentCreator(IFileNamer fileNamer, IRepository repository)
{ ... }
...you can see what the dependencies are. You can also easily mock those dependencies for unit testing, to ensure that you isolate the DocumentCreator and can know that any test failures are a result of its code rather than code in one of its dependencies.
If, on the other hand, you do this...
class DocumentCreator(IDependencyContainer container)
{ ... }
...you've obscured the dependencies. You can't know, without examining the internals of the class, that it requires an IFileNamer and an IRepository.
Nor can you easily know what mocks you need to put in the container in order to test DocumentCreator. Mocking the IDependencyContainer won't help you at all; your class will still fail in testing because the container won't contain an IFileNamer and an IRepository, unless you examine the internals of the class to see that they're required.
What you describe is a ServiceLocator. This is considered an anti-pattern in modern application design. This article describes why.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With