I have a service that I want to share between other transient services. Right now it's not really a service, but in real life application it will. How would I share my service using dependency injection?
I added some demo code below. The SharedService should be the same object for MyTransientService1 and MyTransientService2 in the "Scope" of MyCreatorService.
The second assert fails, while this is what I'd like to accomplish.
class Program
{
static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
private static IHostBuilder CreateHostBuilder(string[] args)
=> Host.CreateDefaultBuilder(args)
.ConfigureServices((_, services) =>
{
services.AddScoped<SharedService>();
services.AddTransient<MyTransientService1>();
services.AddTransient<MyTransientService2>();
services.AddTransient<MyCreatorService>();
services.AddHostedService<MyHostedService>();
});
}
public class SharedService
{
public Guid Id { get; set; }
}
public class MyTransientService1
{
public SharedService Shared;
public MyTransientService1(SharedService shared)
{
Shared = shared;
}
}
public class MyTransientService2
{
public SharedService Shared;
public MyTransientService2(SharedService shared)
{
Shared = shared;
}
}
public class MyCreatorService
{
public MyTransientService1 Service1;
public MyTransientService2 Service2;
public MyCreatorService(MyTransientService1 s1, MyTransientService2 s2)
{
Service1 = s1;
Service2 = s2;
}
}
public class MyHostedService : BackgroundService
{
private readonly IServiceProvider _serviceProvider;
public MyHostedService(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
protected override Task ExecuteAsync(CancellationToken stoppingToken)
{
var creator1 = _serviceProvider.GetRequiredService<MyCreatorService>();
var creator2 = _serviceProvider.GetRequiredService<MyCreatorService>();
Assert.That(creator1.Service1.Shared.Id, Is.EqualTo(creator1.Service2.Shared.Id));
Assert.That(creator1.Service1.Shared.Id, Is.Not.EqualTo(creator2.Service1.Shared.Id));
return Task.CompletedTask;
}
}
IServiceProvideris the root provider. That's what is causing your problem. The solution is to start a new scope usingserviceProvider.CreateScope()inside the hosted service's methods.