首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AddSingleton - lifetime -类需要实现IDisposable吗?

AddSingleton - lifetime -类需要实现IDisposable吗?
EN

Stack Overflow用户
提问于 2019-08-11 14:42:23
回答 2查看 877关注 0票数 2

当为使用AddScopedAddSingleton添加的服务使用DI时,服务是否需要实现IDisposable (即使它不使用任何非托管资源,如文件)?

下面是来自Microsoft Docs的示例:

代码语言:javascript
复制
// Services that implement IDisposable:
public class Service1 : IDisposable {}
public class Service2 : IDisposable {}
public class Service3 : IDisposable {}

public interface ISomeService {}
public class SomeServiceImplementation : ISomeService, IDisposable {}

public void ConfigureServices(IServiceCollection services)
{
    // The container creates the following instances and disposes them automatically:
       services.AddScoped<Service1>();
       services.AddSingleton<Service2>();
       services.AddSingleton<ISomeService>(sp => new SomeServiceImplementation());

    // The container doesn't create the following instances, so it doesn't dispose of
    // the instances automatically:
       services.AddSingleton<Service3>(new Service3());
       services.AddSingleton(new Service3());
}

如果我有这样的代码,会发生什么:

代码语言:javascript
复制
public class Service0  // (doesn't implement Disposable) 

services.AddScoped<Service0>();   // what happens to it when request scope ends? Does it stay on the heap?

services.AddSingleton<Service0>();   // it lives till application dies
services.AddSingleton(new Service0());  // ??
services.AddSingleton<IConfigureOptions<Service0>>((ctx) =>
   {
          return new ConfigureNamedOptions<Service0>(null, (config) =>
   {
// Do something here -- in debug mode it is executing this logic for each request
}}  // it is returning "new Service0" when a request is made. Does it mean for each request it returns new object and keeps in heap memory or returns same previously created object?
EN

回答 2

Stack Overflow用户

发布于 2019-08-11 17:42:39

确实需要服务实现IDisposable(即使它没有使用任何非托管资源,如文件)

通常不会,因为IDisposable的主要目的是允许释放非托管资源。然而,实现IDisposable还有一个额外的原因。Dispose()方法有时用作完成在构造函数中启动的操作的钩子。例如,构造函数开始持续时间测量,而Dispose()停止测量并将持续时间报告给某个监控机制。

关于IDisposable的一些背景知识

如果一个对象没有实现IDisposable,并不意味着它停留在堆中。事实上,GC甚至不知道IDisposable是什么。这个接口只是一个模式。但是,编译器知道IDisposable,并且在using语句作用域的末尾发出对Dispose()的调用。

此外,在许多情况下,基础架构层或库(如ASP.NET核心中的DI )会检查对象是否实现了IDisposable,如果实现了,则对其调用Dispose()

因此,对象实现IDisposable本身并不能保证Dispose()会在GC之前被调用。这取决于对象的用户。为了在GC之前实际确保Dispose(),一次性模式的完整实现包括从“析构函数”调用Dispose()

当请求作用域结束时,它会发生什么?会留在堆里?当请求作用域结束时,它会发生什么?

  • AddScoped<Service0>():在请求的末尾,对对象的引用被“遗忘”( GC可以随时删除它)。就在忘记引用之前,检查对象是否实现了IDisposable,如果实现了,将在web主机生命周期结束时在it.
  • AddSingleton<Service0>():上调用Dispose(),对对象的引用被“忘记”( GC可以随时删除它)。就在忘记引用之前,检查对象是否实现了IDisposable,如果实现了,将在web主机生命周期结束时在it.
  • AddSingleton(new Service0()):上调用Dispose(),对对象的引用被“忘记”( GC可以随时删除它)。但是因为这个对象是从外部提供的,而不是由DI实例化的,所以不会检查它是否有IDisposable,也不会调用Dispose
票数 3
EN

Stack Overflow用户

发布于 2019-08-11 16:36:32

IDisposable只是一个接口,它为实现者类提供了对对象销毁进行清理的机会,它本身并不做任何事情。DI将销毁实例取决于它们的生命周期,如作用域、瞬态、单例,对象在销毁后是否在堆上存在是Gorbagge收集器的职责。如果您在Singleton中定义了一个新实例,则该对象将随Singleton实例一起销毁,且由于Singleton的生命周期一直到应用程序生命周期的末尾,因此它将遵循其父实例的生命周期,除非您在其中执行一些非托管操作。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57447881

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档