I have a Repository service that should be Transient. It is used in many applications.
I have a new application that's a Console App, and current guidance suggests implementing my business logic in Worker Services and adding them to the Generic Host with
One of those Worker Services uses that Repository, so I'm also adding the Repository to my dependency injection container. Thus:
This fails under .NET Core 3.1 because it won't let a Singleton consume a Transient service. That makes sense; you don't want the Transient service to vanish when you might want to use it later. But I didn't ask for a Singleton! What's going on?
The answer is that in .NET Core 2.2
AddHostedService creates a Transient service but in .NET Core 3.1 it creates a Singleton service. The official line is that if your Worker Service needs to consume a Transient service you should just instantiate a new Service Scope and implement... a service locator? Really? So now I can't use regular dependency injection in the service constructor?
Microsoft's rationale for making Worker Services Transient prior to .NET Core 3.x seems solid to me: You only instantiate them once, so there's no need to force you into a Singleton pattern.
So my question has a few parts:
- Is Microsoft really asking me to apply a Service Locator in places where it wasn't called for until .NET Core made stuff weird?
- Do I have to rewrite all my Worker Services to work with .NET Core 3.x now?
- Doesn't this Service Locator strategy circumvent the reason why they prevented Singletons from consuming Transient services in the first place?
My point, and I do have one, is that don't understand why Microsoft imposes a Singleton pattern on the Worker Service that makes it impossible for it to consume Transient services and then recommends a workaround that a) is a well-known antipattern; and b) exactly undermines the utility of not allowing Singletons to consume Transients in the first place.
What is going on here that I don't understand?