I have the following code:
builder.Services.AddSingleton<IAvailabilityWorker, AvailabilityWorker>();
builder.Services.AddHostedService<AvailabilityWorker>();
There is a timer in the service with a public function void set_last_time(DateTime time)
But I can't seem to get the dependency injection working. If I inject IAvailabilityWorker into the constructor it works but the time is set for another instance besides the singleton one. Even though there shouldn't be. If I try injecting AvailabilityWorker itself, it only works if I use it without Interface
builder.Services.AddSingleton<AvailabilityWorker>();
But I need the interface registration for testing.
How can I get it working while keeping the interface tied to the implementation?
What you are dealing with is a problem commonly known as Torn Lifestyle. The lifestyle of AvailabilityWorker
is said to be torn, because it is registered twice; once as singleton and a second time as transient. This is because AddHostedService
under the covers calls AddTransient
.
To ensure a single AvailabilityWorker
instance to exist for the lifetime of your application, you should change the registrations to the following:
Services.AddSingleton<AvailabilityWorker>();
Services.AddSingleton<IAvailabilityWorker>(
c => c.GetRequiredService<AvailabilityWorker>());
Services.AddSingleton<IHostedService>(
c => c.GetRequiredService<AvailabilityWorker>());