假设我有以下C#类ClassA:

public class ClassA
{
    private readonly ClassB _b;

    public ClassA(ClassB b)
    {
        _b = b;
    }
}

此类包含对ClassB的实例的引用,该实例实现IDisposable:

public class ClassB : IDisposable
{
    public void Dispose()
    {
        // dispose
    }
}

现在,我通过依赖项注入将ClassA注册为服务,并创建ClassB的实例并将其传递给它:

services.AddSingleton(service => new ClassA(new ClassB()));

在服务的生命周期结束时,是否调用了类B的Dispose()方法?根据this stackoverflow post regarding the disposal of singleton instances,如果ClassA也将实现IDisposable,那么ClassADispose()方法也将被调用.我是否也要为ClassA实现接口,并在ClassADispose()中调用ClassBDispose()?或者,我能以某种方式确保在ClassA中不实现IDisposable的情况下调用ClassBDispose()方法吗?

编辑:我将菲利普·斯图克的答案标记为正确,因为它似乎为这个问题推荐了最简单的解决方案.关于我的第Is the 101 method of 102 ever called?个问题,我认为下面的讨论清楚地表明它不是被要求的.相反,GC通过调用ClassB的实例上的Finalize method instead of the Dispose method来清理它.

推荐答案

如果您更改了将事物注册到控制反转容器的方式,那么您根本不必实现iDisposable:

services.AddSingleton<ClassB>(ClassB);
services.AddSingleton<ClassA>(ClassA);

当您请求ClassA的实例时,它会查看构造函数,发现它需要ClassB.因此,您让容器解析ClassA,而不是自己控制它.

然后,当应用程序关闭时,将根据需要在ClassB上调用Dispose

通过全程反转控制并为A类和B类制作接口,可以进行进一步的改进.然后,ClassA将包含对接口的引用,而不是类.这就是依赖倒置的全部意义所在.

Csharp相关问答推荐

利用.NET 8中的AddStandardResilienceDeliveries和AddStandardHedgingDeliveries实现Resiliency

Regex在c#中完全匹配

Monty Hall游戏节目模拟给我50/50的结果

"virtual"修饰符对接口成员有什么影响?

Elasticsearch:当我try 使用c#将嵌套对象添加到filter中时出现问题

在发布表单时绑定包含附加(嵌套)列表的对象列表的正确语法是什么

WPF DataGrid中的三维数据

可为空的泛型属性

不带身份的Blazor服务器.Net 8 Cookie身份验证

从c#列表中删除额外的对象&对象&>从ASP.NET WebForm返回json响应

如何在没有前缀和可选后缀的情况下获取Razor Page Handler方法名称?

附加标题不起作用,而添加则起作用

如何捕获对ASP.NET核心应用程序的所有请求并将其发送到一个页面

如何避免在.NET中将日志(log)写入相对路径

如何在.NET MAUI中最大化GraphicsView的大小?

如何使用.NET Aspire从Blazor应用程序与GRPC API通信?

数据库操作预计影响1行,但实际影响0行; after _dbContext.SaveChanges();

无法向Unity注册Microsoft Logger

Xamarin中出错.表单:应用程序的分部声明不能指定不同的基类

Unity 3D-意外轴捕捉和未知力对脉冲react 行为的影响