Nested classes depend on execution scope using ServiceManager

PROBLEM

  1. we use ZF2 and have ServiceLocator inside many classes.
  2. to migrate to ZF3/Laminas docs suggest to inject all dependencies inside class using Factory

EXAMPLE
for ZF2, where we have ServiceLocator everywhere:

  1. we have main ClassA, which have as parameter URL-string. we get its instance from Factory using ServiceLocator
  2. on runtime ClassA make curl-request to URL and gets response
  3. ClassA detects type of response (HTML, file, XML, JSON, …)
  4. ClassA calls ServiceLocator (it calls Factory) to get appropriate ClassX dependently to type of response (HTML_Adapter, File_Adapter, XML_Adapter, JSON_Adapter, …, 100+ other adapters), which will parse data using own logic and return the result

to simplify i described only 2 levels of nesting, but in reality it can be deeper and each level potentially can depend on execution scope.

if we are speaking about ZF3/Laminas then we should:
a) remove ServiceLocator from everywhere
b) build whole ClassA with all deep dependencies using Factory and inject it into controller before action will be run

as we can see we unable to build ClassA, because we don’t know which concrete dependency we will need as this information we will get after ClassA will start own execution.

or we should inject ALL 100+ adapters into ClassA, but in reality we will need ONLY 1 of them (it looks like performance issue). and also can exist other nuances, which will not allow to initiate all of them due to absented input data before execution of parent class starts.

question:

  1. so what is the best practice in such case?
  2. how to implement resolving nested classes in ZF2/ZF3/Laminas using Factory (and ServiceLocator) if each deeper level of nested classes depends on execution scope?

Hello and welcome to our forums! :smiley:

Correct this is a big problem and always been wrong, also in ZF2.

Remove it from everywhere. Do not inject the entire service container / manager!


Check the concept of plugin managers:

It is widely used in various components like:

Or create separate container based on the PSR-11 container interface which handles only your adapters.