Reputation: 45
Why the ScopedOperation constructor was not called after a second scope creation?
Source: https://dotnetfiddle.net/wtyP9n
using System;
using Microsoft.Extensions.DependencyInjection;
public class Program
{
public static void Main()
{
Adding the services:
var serviceProvider = new ServiceCollection()
.AddTransient<TransientOperation>() //Create a Simple Transient Service that writes a text on creation
.AddScoped<ScopedOperation>() //Create a Simple Scoped Service that writes a text on creation
.AddSingleton<SingletonOperation>() //Create a Simple Singleton Service that writes a text on creation
Building the services and making the first request:
serviceProvider.BuildServiceProvider();
Console.WriteLine("Initiating Service Operations");
Console.WriteLine("\n-------- First Request --------");
//With the scope the aim is to see if after the using(), which service will be destroyed
using (var scope = serviceProvider.CreateScope())
{
var singletonService = serviceProvider.GetService<SingletonOperation>();
var scopedService = serviceProvider.GetService<ScopedOperation>();
var transientService = serviceProvider.GetService<TransientOperation>();
} //Why the disposed methods of Scoped and Transient Services are not being called ?
Going forward to Second Request:
Console.WriteLine("\n-------- Second Request --------");
using (var scope = serviceProvider.CreateScope()) //adding the same singleton, scope and transient services agains
{
var singletonService = serviceProvider.GetService<SingletonOperation>();
var scopedService = serviceProvider.GetService<ScopedOperation>();
var transientService = serviceProvider.GetService<TransientOperation>();
} //Why the disposed methods of Scoped and Transient Services are not being called ?
Console.WriteLine();
Console.WriteLine(new String('-',30));
Console.WriteLine("Operations Concluded!");
Console.ReadLine();
}
}
//DEFINING THE SERVICES
Services:
public class SingletonOperation:IDisposable
{ private bool _disposed = false;
public SingletonOperation() => Console.WriteLine("Singleton Service created!");
public void Dispose() { if (_disposed) return; Console.WriteLine("SingletonService Disposed!"); _disposed = true;}
~SingletonOperation() => Dispose();
}
public class ScopedOperation:IDisposable
{
private bool _disposed = false;
public ScopedOperation() => Console.WriteLine("Scoped Service created!");
public void Dispose() { if (_disposed) return; Console.WriteLine("ScopedService Disposed!");_disposed = true; }
~ScopedOperation()=>Dispose();
}
public class TransientOperation:IDisposable
{ private bool _disposed = false;
public TransientOperation() => Console.WriteLine("Transient Service created!");
public void Dispose(){ if (_disposed) return; Console.WriteLine("TransientService Disposed!"); _disposed = true; }
~TransientOperation() => Dispose();
}
Showing full Results:
Observe that on the Second Request, the Transient Service constructor was called, but I was expecting also the ScopedService Constructor to also be called since it is in a different scope. Why it was not called ?
Upvotes: 1
Views: 1102
Reputation: 247008
//Why the disposed methods of Scoped and Transient Services are not being called ?
Your example's provider is not being disposed so its created services wont be disposed either. All the GetService
calls in your example belong to the same scope.
Use the provider of the created scope to get the desired behavior
//...
using (IServiceScope scope = serviceProvider.CreateScope()) {
var singletonService = scope.ServiceProvider.GetService<SingletonOperation>();
var scopedService = scope.ServiceProvider.GetService<ScopedOperation>();
var transientService = scope.ServiceProvider.GetService<TransientOperation>();
}
//...
Making the changes above to the provided fiddle yielded the following output
Initiating Service Operations
-------- First Request --------
Singleton Service created!
Scoped Service created!
Transient Service created!
TransientService Disposed!
ScopedService Disposed!
Executing DemoService Operation number: 0
Executing DemoService Operation number: 1
Initialized valued on service was: 10
Adding object of type Client
I am Service A
I am Service B
I am Service B
-------- Second Request --------
Scoped Service created!
Transient Service created!
TransientService Disposed!
ScopedService Disposed!
------------------------------
Operations Concluded!
Upvotes: 4