使用带有 Microsoft.Extensions.DependencyInjection 库的服务进行依赖注入

问题描述

为什么在创建第二个作用域后没有调用 ScopedOperation 构造函数

来源:https://dotnetfiddle.net/wtyP9n

enter image description here

using System;
using Microsoft.Extensions.DependencyInjection;
                    
public class Program
{
    public static void Main()
    {

添加服务:

        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

构建服务并发出第一个请求:

         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 ?

继续第二次请求:

         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

服务:

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();
}

显示完整结果:

Results

观察到在第二个请求中,瞬态服务构造函数调用,但我也期待 ScopedService 构造函数也是 调用是因为它在不同的范围内。为什么不叫?

解决方法

//为什么没有调用Scoped和Transient Services的dispose方法?

您示例的提供程序没有被释放,因此它创建的服务也不会被释放。您示例中的所有 Button accept = new Button(); accept.Width = 51; accept.Height = 23; accept.Location = new Point(157,23); accept.Text = "Accept"; accept.Click += new EventHandler(acceptFriendRequestService); accept.Tag = names[nameCounter].ToString(); void acceptFriendRequestService(object sender,EventArgs e) { var name = ((Button)sender).Tag; //Do your work here. } 调用都属于同一范围。

使用所创建范围的提供者来获得所需的行为

GetService

对提供的小提琴进行上述更改产生以下输出

//...

using (IServiceScope scope = serviceProvider.CreateScope()) {
    var singletonService = scope.ServiceProvider.GetService<SingletonOperation>();  
    var scopedService = scope.ServiceProvider.GetService<ScopedOperation>();  
    var transientService = scope.ServiceProvider.GetService<TransientOperation>();  
} 

//...

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...