【问题标题】:How to make ServiceProvider to call Dispose on objects created manually?如何让 ServiceProvider 对手动创建的对象调用 Dispose?
【发布时间】:2019-02-24 23:52:12
【问题描述】:

我正在使用Microsoft.Extensions.DependencyInjection(默认实现)。我注意到,当我将对象添加为单例时,ServiceProvider 会忽略对象上的 IDisposable

var instance = new MyDisposableObj();
ServiceLocator.Instance = instance;

var services = new ServiceCollection();
services.AddSingleton( instance );
var container = services.BuildServiceProvider();
container.Dispose();

看起来微软认为我必须手动处理手动创建的对象。

但是,当我为 ServiceCollection 进行扩展时,我想封装我的对象的处置。我不应该强迫我的扩展的用户手动处理我的对象!

那么,是否有可能改变这种行为?

【问题讨论】:

  • 改变什么行为?您希望什么时候处理该对象?
  • 处置其他人的单身将是一个很好的拖钓:)...通常,如果它是真正的单身,如果不重新启动应用程序,就不可能将其恢复到“未处置状态” - 所以我我不确定为什么您希望容器在这种情况下拥有所有权(特别是如果您可以创建多个容器)
  • 顺便说一句,“看起来微软认为我必须手动处理手动创建的对象”一次性对象应始终由具有 (last) 的代码处理他们的所有权(不受规则约束)。我在这里感觉到对 IDisposables 的根本误解吗?
  • @Alexei Levenkov 这是我的对象。我创建它并添加到 ServiceCollection。
  • 我应该手动创建ServiceDescriptor吗?

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


【解决方案1】:

我知道这是旧的,但也许有助于澄清一点。
您可以自己创建对象并使用实现工厂进行注册。 DI 将负责处理对象,因为它通过调用工厂方法来获取它的所有权。
在msdn中有描述。

var instance = new MyDisposableObj();
var services = new ServiceCollection();
services.AddSingleton(x => instance);
var container = services.BuildServiceProvider();
container.Dispose();

您可以通过简单的单元测试来验证这一点

[Fact]
public void ServiceProvider_SingletonObjectAddedAsFactory_IsDisposedWithContainer()
{
        // Arrange
        var sc = new ServiceCollection();
        var fake = A.Fake<IDisposable>();
        sc.AddSingleton(x => fake);

        // Act
        var sp = sc.BuildServiceProvider();
        var recieved = sp.GetService<IDisposable>();
        sp.Dispose();

        // Assert
        recieved.Should().NotBeNull();
        A.CallTo(() => fake.Dispose()).MustHaveHappenedOnceExactly();
}

【讨论】:

    【解决方案2】:

    我认为还有另一种选择 - 更合适。查看服务提供者。它实现了 IDisposable。这意味着您应该通过 using 语句创建 ServiceProvider:

    使用(var provider = collection.BuildServiceProvider()) { var service1 = provider.GetRequiredService(); }

    仅此而已。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多