.NET Core 依赖注入容器不调用 Dispose()

.NET Core Dependency Injection container not calling Dispose()

我不知道为什么 Dispose() 在程序结束时没有被调用。我编写了一个控制台应用程序来帮助测试 Azure Functions 应用程序。 类 之一实现了 IDisposableDispose() 从未被调用。我扩展了我的示例,以查看实现 IDisposable 的依赖服务是否调用了 Dispose() 方法,但没有调用。我今天早上刚更新到16.9.4,目标框架是.NET 5。示例代码如下:

public class CustomOptions
{
    public const string Section = "CustomSettings";
    public string Url { get; set; }
    public bool UseHttps { get; set; }
}
public interface IDisposableService
{
    void DoSomething();
}
public class DisposableService : IDisposableService, IDisposable
{
    public void Dispose()
    {
        Console.WriteLine("Disposing a disposable service");
        GC.SuppressFinalize(this);
    }

    public void DoSomething()
    {
        Console.WriteLine("I'm doing some work");
    }
}
public interface IConsoleService
{
    void Run(string[] args);
}
public class ConsoleService : IConsoleService, IDisposable
{
    private readonly ILogger<ConsoleService> _logger;
    private readonly CustomOptions _options;
    private readonly IDisposableService _service;


    public ConsoleService(IDisposableService service,
                          ILogger<ConsoleService> logger,
                          IOptions<CustomOptions> options)
    {
        _service = service;
        _logger = logger;
        _options = options.Value;
    }

    public void Dispose()
    {
        Console.WriteLine($"Disposing {nameof(ConsoleService)}");
        GC.SuppressFinalize(this);
    }

    public void Run(string[] args)
    {
        _logger.LogInformation("The application is now starting {Start}", DateTime.Now);
        Console.WriteLine($"The Url in the settings file is '{_options.Url}'");
        _service.DoSomething();
    }
}
class Program
{
    static void Main(string[] args)
    {
        IHost host = Host.CreateDefaultBuilder()
            .ConfigureServices((context, services) =>
            {
                services.Configure<CustomOptions>(
                    context.Configuration.GetSection(CustomOptions.Section));

                services.AddTransient<IDisposableService, DisposableService>();
                services.AddTransient<IConsoleService, ConsoleService>();

                services.AddLogging();
                services.AddOptions();
            })
            .Build();

        IConsoleService service =
            ActivatorUtilities.CreateInstance<ConsoleService>(host.Services);
        service.Run(args);
    }
}
appsettings.json
{
    "Logging": {
        "LogLevel": {
            "Default": "Information",
            "Microsoft": "Warning",
            "Microsoft.Hosting.Lifetime": "Warning"
        }
    },
    "CustomSettings": {
        "Url": "www.contoso.com",
        "UseHttps":  true
    }
}

程序的输出是:

info: ConsoleApp.ConsoleService[0]
The application is now starting 04/14/2021 10:30:54
The Url in the settings file is 'www.contoso.com'
I'm doing some work

非常感谢任何帮助。


使其正常工作的更改如下:

  1. IDisposable添加到IConsoleService
public interface IConsoleService, IDisposable
{
    void Run(string[] args);
}
  1. 并将其从 ConsoleService
  2. 中删除
public class ConsoleService : IConsoleService
{
  1. IHost 变量包装在 using 语句中或调用 host.Dispose()

  2. 使用IServiceProvider.GetService<>()代替ActivatorUtilities.CreateInstance<>()

    host.Services.GetService<IConsoleService>().Run(args);
    host.Dispose();

这是一个仅使用 ServiceCollection

的示例
IServiceCollection services = new ServiceCollection();
services.AddSingleton<Application>(); // your application which implement RunAsync
using var serviceProvider = services.BuildServiceProvider();
await serviceProvider.GetService<Application>().RunAsync();