如何在 .NET 7 中使用依赖注入来处理实现 IAsyncDisposable 的服务

问题描述 投票:0回答:1

我有一个使用

IAsyncDisposable
接口的服务,因为它拥有一个具有接口本身的对象。

public class AddressImporter : IAddressImporter
{
    private readonly IConsumer<Model> _consumer; // implementing IAsyncDisposable
}

我这样注册服务:

services.AddTransient<IAddressImporter, AddressImporter>();
然后像这样将它注入到我的主要服务中:

public MainService(IAddressImporter addressImporter) {
    _addressImporter = addressImporter;
}

这样会不会泄露资源?如果是这样,我该如何改进它,所以在我的主要服务中出现任何异常时都调用

DisposeAsync

我正在考虑将

IAsyncDisposable
添加到
IAddressImporter
并在任何异常或我的
IAddressImporter.DisposeAsync
结束时调用
MainService

编辑: 尝试使用服务时

public class AddressImporter : IAddressImporter
{
    private readonly IConsumer<Model> _consumer; // implementing IAsyncDisposable
    public async ValueTask DisposeAsync()
    {
        _logger.Information("Disposing {ResourceName}", nameof(PulsarAddressImporter));
        await _consumer.DisposeAsync();
        GC.SuppressFinalize(this);
    }

}

我得到例外:

BackgroundService 失败 System.InvalidOperationException:'AddressService.Web.Jobs.Test' 类型仅实现 IAsyncDisposable。使用 DisposeAsync 来处置容器。 System.InvalidOperationException:“AddressService.Web.Jobs.Test”类型仅实现 IAsyncDisposable。使用 DisposeAsync 来处置容器。 [15:23:56 INF] 应用程序正在关闭...

c# .net dependency-injection idisposable iasyncdisposable
1个回答
3
投票

这会不会泄露资源?

这取决于父对象和作用域的生命周期——由内置 DI 容器创建的服务在作用域被释放时自动释放:

class MyTransient : IAsyncDisposable
{
    public bool Disposed { get; set; }
    public ValueTask DisposeAsync()
    {
        Disposed = true;
        return ValueTask.CompletedTask;
    }
}

var services = new ServiceCollection();
services.AddTransient<MyTransient>();

var serviceProvider = services.BuildServiceProvider();
MyTransient myTransient;
await using (var scope = serviceProvider.CreateAsyncScope())
{
    myTransient = scope.ServiceProvider.GetRequiredService<MyTransient>();
}

Console.WriteLine(myTransient.Disposed); // prints True

因此,除非服务是从根服务创建的,否则当所有者范围结束时,它将与其他所有内容一起处理,因此使

AddressImporter
实施
IDisposable/IAsyncDisposable
应该可以解决问题(如果异常导致所有者范围结束)。

© www.soinside.com 2019 - 2024. All rights reserved.