.NET Core 依赖注入容器不调用 Dispose()
.NET Core Dependency Injection container not calling Dispose()
我不知道为什么 Dispose()
在程序结束时没有被调用。我编写了一个控制台应用程序来帮助测试 Azure Functions 应用程序。 类 之一实现了 IDisposable
但 Dispose()
从未被调用。我扩展了我的示例,以查看实现 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
非常感谢任何帮助。
使其正常工作的更改如下:
- 将
IDisposable
添加到IConsoleService
public interface IConsoleService, IDisposable
{
void Run(string[] args);
}
- 并将其从
ConsoleService
中删除
public class ConsoleService : IConsoleService
{
将 IHost
变量包装在 using
语句中或调用 host.Dispose()
使用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();
我不知道为什么 Dispose()
在程序结束时没有被调用。我编写了一个控制台应用程序来帮助测试 Azure Functions 应用程序。 类 之一实现了 IDisposable
但 Dispose()
从未被调用。我扩展了我的示例,以查看实现 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
非常感谢任何帮助。
使其正常工作的更改如下:
- 将
IDisposable
添加到IConsoleService
public interface IConsoleService, IDisposable
{
void Run(string[] args);
}
- 并将其从
ConsoleService
中删除
public class ConsoleService : IConsoleService
{
将
IHost
变量包装在using
语句中或调用host.Dispose()
使用
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();