【问题标题】:Dispose being called multiple times by Microsoft DependencyInjectionMicrosoft DependencyInjection 多次调用 Dispose
【发布时间】:2019-01-25 12:20:11
【问题描述】:

我注册了两次课程,但合同不同。

services
    .AddSingleton<MyClass>()
    .AddSingleton<IHostedService>(sp => sp.GetService<MyClass>());

该类还实现了IDisposable,这意味着将在应用程序关闭时调用 Dispose 方法。但是因为注册了两次,所以会被调用两次。

Autofac 有两种方法可以解决这个问题:

builder.RegisterType<MyClass>().AsSelf().As<IHostedService>();
//or
builder.RegisterType<MyClass>().AsSelf();
builder.Register(ctx => ctx.Resolve<MyClass>()).As<IHostedService>().ExternallyOwned();

但似乎无法在 ASP.NET Core 中使用 Microsoft DependencyInjection 执行任何操作。有办法解决吗?

【问题讨论】:

  • 从技术上讲,它不应该让你添加相同类型的单例两次;这就是它是单例的全部原因。既然这样,我相信您可以自行设置不同的设置。基于这个问题,我自己从未尝试过;我个人觉得这是框架中的 2 个不同的错误。
  • Kirk Larkin 也是正确的,但并非所有 Disposable 类型都如此;很遗憾。如果您正在设计 Disposable 类型,那么我建议遵循该规则。
  • 第二个不是类型注册。你注册了一个工厂方法,工厂方法解析MyClass,所以两者都是完全相同的实例
  • @Tseng 是的,它们是同一个实例。这就是为什么它这样注册的全部想法。
  • @KirkLarkin 看不到 Duncan 的任何回答。

标签: c# asp.net-core dependency-injection autofac


【解决方案1】:

Dispose 方法将在应用程序关闭时调用。但是由于它注册了两次,所以会被调用两次。 . . .有办法解决吗?

是的。问题出在您的 IDisposable 实现中:

如果一个对象的 Dispose 方法被多次调用,该对象 必须忽略第一个呼叫之后的所有呼叫。物体不得抛出 如果多次调用其 Dispose 方法,则会出现异常。实例 Dispose 以外的方法在以下情况下可能会引发 ObjectDisposedException 资源已被释放。

IDisposable.Dispose

【讨论】:

  • 这表明行为应该不是问题。但是假设您正在处理来自第 3 方的写得很糟糕的 Dispose()?
  • @HenkHolterman 然后将其包装在行为正确的服务类型中并注册。
  • 是的,可以解决。但是那个包装器可能会很麻烦。它并不能完全免除 DI。这可能使这是一个功能请求。
  • 我的 IDisposable 实现没有问题。但是 Dispose 不应该被调用两次。
  • @Allrameest:你应该时刻准备好一个 dispose 方法可能会被调用两次。还要记住,Dispose 方法永远不应该抛出任何异常,只有类成员可以
猜你喜欢
  • 2019-02-13
  • 2023-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-13
  • 1970-01-01
相关资源
最近更新 更多