Repository navigation
Remove Modular.get() - Service locator (Anti-Pattern) #630
Description
Activity
Hi, @AlvaroVasconcelos.
I agree that service locator has many problems. It's actually a trade-off. It facilitates dependency inversion with the cost of being inherently unsafe.
In the context of Flutter we have some alternatives:
- Passing dependencies by parameter. This is actually my usual choice, as it's statically safe and explicit, but most people don't like it because it's more verbose and cumbersome;
- Using global-variable dependencies, like Riverpod;
- Using code-generation to make the dependency-tree and guarantee that everything is correctly linked. We had
injector.dart, but it has been discontinued, so it would have to be done from-scratch which is really a no-option for most people.
Maybe I am missing some options, but this is the most obvious for me.
In the case of Modular and the way it works I don't think one of this options is viable, but it's obviously open to discussion.
Do you have anything in mind as a viable alternative to the way it's done today?
Has a good discution here (almost 8 years ago, so dis discution is not anything new):
https://stackoverflow.com/questions/22795459/is-servicelocator-an-anti-pattern
My point of view is: you don't like it, so you don't use it.
I see no reason to deprive the use of a feature that is used in thousands of projects just because "Some articles say it's an Anti-Pattern so we should remove support".
One of the reasons I didn't use it was because of the difficulty of testing but the way Modular was written is very testable and you can mock and overwrite only what you need from a given Module.
Hi!
Thanks for your contribution (@AlvaroVasconcelos ). Here are my thoughts on the matter.
(Service Locator violates SOLID)
- I believe there is no violation, as it is not a common implementation. The implementation of an SL uses its own interfaces. So there is no violation.
(Service Locator violates encapsulation)
- Quite the opposite. The SL is just an encapsulation of the injection system, which makes it completely testable. Perhaps the way it has been used (Modular.get) directly sets up some coupling, but Modular.get is not a static method. It returns an object that can be passed to the class.
Those are my points about. I would love to see more comments on the subject.
Service Locator is it's actually an anti-pattern and should be avoided.
the problem with Service Locator is that it hides a class' dependencies, causing run-time errors instead of compile-time errors, as well as making the code more difficult to maintain because it becomes unclear when you would be introducing a breaking change.
Service Locator violates SOLID:
Violates the Interface Segregation Principle (ISP). That's because a Service Locator effectively has infinitely many members.
Service Locator violates encapsulation:
Violates encapsulation in statically typed languages because it doesn't clearly communicate preconditions.