Currently developing futuristic smart-device, IoT connected, highway construction site safety system in EU.
Used to work on infrastructure, application architecture and cloud engineering.
service locator indeed is an antipattern in the following sense:
Imagine seeing source code of a service which depends on a Service Locator (in Microsoft DI world called ServiceProvider).
It is not immediately clear what the service dependencies are because ServiceProvider offers ServiceCollection which is a list of all services registered at startup.
You would have to dig into the source code of that particular service to figure out which services are actually instantiated from the ServiceCollection. If you forget to add required service to the collection your unit tests will happily compile and run, but will crash at runtime when one of the required services cannot be instantiated.
It is also a nightmare to write tests for such class as anytime the developer reponsible for that service adds new service dependency his class signature will not change but your code and tests will probably crash without any obvious reason.
Another modern approach to lazy instantiating dependencies is Factory pattern. Have a look at EF Core (>=5.0.0). They've introduced DBContextFactory which can be injected into DI instead of DBContext. Also Micosoft's Logging framework uses ILoggerFactory which provides CreateLogger() method. Similarly new approach to HttpClient instantiation allows you to inject IHttpClientFactory that produces pooled HttpClient objects on demand.
Hi,
service locator indeed is an antipattern in the following sense:
Imagine seeing source code of a service which depends on a Service Locator (in Microsoft DI world called
ServiceProvider
).It is not immediately clear what the service dependencies are because
ServiceProvider
offersServiceCollection
which is a list of all services registered at startup.You would have to dig into the source code of that particular service to figure out which services are actually instantiated from the
ServiceCollection
. If you forget to add required service to the collection your unit tests will happily compile and run, but will crash at runtime when one of the required services cannot be instantiated.It is also a nightmare to write tests for such class as anytime the developer reponsible for that service adds new service dependency his class signature will not change but your code and tests will probably crash without any obvious reason.
Another modern approach to lazy instantiating dependencies is Factory pattern. Have a look at EF Core (>=5.0.0). They've introduced DBContextFactory which can be injected into DI instead of DBContext. Also Micosoft's Logging framework uses
ILoggerFactory
which providesCreateLogger()
method. Similarly new approach to HttpClient instantiation allows you to injectIHttpClientFactory
that produces pooledHttpClient
objects on demand.I think the key difference here is that LazyProxy doesn't require you to change the "consumption API", and e.g. factory pattern does.