简体   繁体   中英

Dependency injection using Services with Microsoft.Extensions.DependencyInjection library

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?

//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!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM