You mention putting logic in a service constructor as a bad practice, then you say we need to do it in other ways but don’t propose any real solutions. Since we don’t have lifecycle hooks in services, the constructor is the simplest solution we have for initialization.
We could use an application initializer, but that I don’t think that would work for lazy-loaded features which you discuss in that section.
What’s your proposal? Maybe Angular module constructors can initialize services? But that would basically be the same pattern but used in another place.
According Logic inside a service constructor - first of it depends what logic do you need, because in your case service should be singleton, and your example is wrong. It’s not in general bad practice.
Secondly - what with readonly properties? You cannot initialize them outside constructor.
We can use property initializers, but that’s just syntactic sugar for doing it in the constructor.
The thing that made me think about initializing loginc inside a constructor was a piece of code in one of our web apps at work which created a Socket connection inside the constructor. Every time the server was imported in a new module, a new connection was established, which wasn’t the desirable outcome (sometimes only other methods from the service were needed). Essentially, my argument is that we don’t need to write logic inside a service constructor, because
- A constructor is invoked when the module is created, not every time it is injected, while on of the two may be needed depending on context
- Calling an initializer method inside an entity that consumes the service (directive, component, another service) is more explicit and clean, in my opinion
So my proposal is to
- Avoid writing logic inside a service constructor whatsoever
initialize(or another, more explicitly named) method on the service
- Invoke it whenever the logic needs to be reexecuted
- Do not call the method in unit tests, which may allow us to use the service instance itself (instead of a stub, but this is theoretical).
See my other answer on a proposed solution
Also, regarding the
readonly properties - we can initialize them inside a constructor, you are correct, that would be an exception to the rules I proposed