简体   繁体   English

AddSingleton-生存期-类是否需要实现IDisposable?

[英]AddSingleton - lifetime - does class need to implement IDisposable?

When using DI for services added using AddScoped or AddSingleton , does the service need to implement IDisposable (even if it is not using any unmanaged resources like files)? 将DI用于使用AddScopedAddSingleton添加的服务时,该服务是否需要实现IDisposable (即使它未使用文件等任何非托管资源)?

Found below sample from Microsoft Docs: 在Microsoft Docs的以下示例中找到:

// 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());
}

What happens if I have this code: 如果我有以下代码会发生什么:

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?

does the service need to implement IDisposable(even if it is not using any unmanaged resources like files) 服务是否需要实现IDisposable(即使它没有使用文件之类的任何非托管资源)

Usually it doesn't, because the primary purpose of IDisposable is allow releasing unmanaged resources. 通常不会,因为IDisposable的主要目的是允许释放非托管资源。 However, there is an additional reason for implementing IDisposable . 但是,还有另一个原因实现IDisposable The Dispose() method is sometimes used as a hook for completing actions started in the constructor. Dispose()方法有时用作完成构造函数中启动的操作的钩子。 For example, a constructor starts duration measurement, while Dispose() stops the measurement and reports the duration to some monitoring mechanism. 例如,构造函数开始进行持续时间测量,而Dispose()停止进行测量并将持续时间报告给某种监视机制。

A little of backgroiund about IDisposable 关于IDisposable的一些背景知识

If an object doesn't implement IDisposable it doesn't mean it stays in heap. 如果对象没有实现IDisposable ,则并不意味着它会停留在堆中。 In fact, the GC doesn't even know what IDisposable is. 实际上,GC甚至都不知道IDisposable是什么。 This interface is only a pattern. 该界面仅是一种模式。 However, the compiler knows IDisposable , and it emits calls to Dispose() in the end of using statement scope. 但是,编译器知道IDisposable ,并且在using语句作用域的末尾发出对Dispose()调用。

In addition, in many cases infrastructure layers or libraries (such as DI in ASP.NET Core) check if an object implements IDisposable , and if it does, call Dispose() on it. 另外,在许多情况下,基础结构层或库(例如ASP.NET Core中的DI)会检查对象是否实现IDisposable ,如果是,则对它调用Dispose()

So the fact that an object implements IDisposable doesn't by itself guarantee that Dispose() will be called before GC. 因此,对象实现IDisposable的事实本身并不能保证在GC之前调用Dispose() It depends on the users of the object. 它取决于对象的用户。 To actually ensure Dispose() before GC, the full implementation of the disposable pattern includes calling Dispose() from the "destructor". 为了在GC之前实际确保Dispose() ,一次性模式的完整实现包括从“析构函数”中调用Dispose()

what happens to it when request scope ends? 请求范围结束时会发生什么? stays in heap? 留在堆里? what happens to it when request scope ends? 请求范围结束时会发生什么?

  • AddScoped<Service0>() : at the end of the request, the reference to the object is "forgotten" (the GC is free to remove it at any moment). AddScoped<Service0>() :在请求结束时,对该对象的引用被“忘记了”(GC可随时将其删除)。 Just prior to forgetting the reference, the object is checked for whether it implements IDisposable , and if it does, Dispose() will be called on it. 就在忘记引用之前,将检查对象是否实现IDisposable ,如果实现了IDisposable ,则将在该对象上调用Dispose()

  • AddSingleton<Service0>() : at the end of the web host lifetime, the reference to the object is "forgotten" (the GC is free to remove it at any moment). AddSingleton<Service0>() :在Web主机生存期结束时,对该对象的引用已“被遗忘”(GC可随时将其删除)。 Just prior to forgetting the reference, the object is checked for whether it implements IDisposable , and if it does, Dispose() will be called on it. 就在忘记引用之前,将检查对象是否实现IDisposable ,如果实现了IDisposable ,则将在该对象上调用Dispose()

  • AddSingleton(new Service0()) : at the end of the web host lifetime, the reference to the object is "forgotten" (the GC is free to remove it at any moment). AddSingleton(new Service0()) :在Web主机生存期结束时,对该对象的引用被“忘记了”(GC可随时将其删除)。 But since this object was supplied from the outside and not instantiated by the DI, it won't be checked for IDisposable and the Dispose won't be called. 但是由于此对象是从外部提供的,并且未由DI实例化,因此不会检查其IDisposable ,也不会调用Dispose

IDisposable is just an interface which give the implementer class the chance to do some cleanup on object destruction , it does not do anything by itself. IDisposable只是一个接口,它使实现者类有机会对对象破坏进行一些清理,它本身不会做任何事情。 DI will destroy the instances depends on their lifetime like scoped , transient , Singleton, will the object exists after destruction on the heap is the Gorbagge Collector's duty to decide . DI将根据实例的生命周期(如作用域,瞬态,Singleton)销毁实例,销毁后将对象存在于堆上是Gorbag​​ge Collector的职责。 If you define a new instace inside a Singleton that object will be destroyed with the Singleton instace and due to lifetime of the Singleton which is till the end of the application's lifetime therefore it will follow it's parent's lifetime , except if you do some unmanaged operation there. 如果您在Singleton内部定义了一个新的实例,则该对象将被Singleton实例破坏,并且由于Singleton的生命周期一直到应用程序生命周期的尽头,因此它将遵循其父对象的生命周期,除非您在那里进行一些非托管操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM