对于常规情况,如何管理一次性用品,例如如何在 ASP.NET Core 应用程序关闭时正确安全地处置容器中注册的单例实例,解释了如何执行此操作。
但我有一个稍微不同的情况 - 我没有像这里这样的一些工人IFoo
的单个实例:
interface IFoo : IDisposable // not my case
您知道如何处置,只需在IFoo
实例上调用Dispose
即可。
不,我的IFoo
不是IDisposable
:
interface IFoo // my case
而不是单个实例,我在创建时有一对实例 -(IFoo,IDisposable)
.当我必须做实际工作时,我使用第一项,因为那里有所有的逻辑,当我完成时,我会在第二项上调用Dispose
。
你可以说这是极端的脱钩。
当我在 ASP.NET Core 时,我对 DI 有问题——我有一对像上面这样的,我可以注册IFoo
例如services.AddScoped
,但是如何告诉services
手头有不同/单独的IDisposable
,当工作完成并且范围消失时应该处理?
您可以在(IFoo, IDisposable)
周围创建一个包装器,假设:
public class DisposableFoo : IDisposable
{
// Assume FooConcrete implements IFoo and IDisposable
private readonly FooConcrete _foo;
public DisposableFoo(FooConcrete fooConcrete) { _foo = fooConcrete; }
public IFoo Instance => _foo;
public void Dispose() => _foo.Dispose();
}
然后,在Startup.cs
中,您可以执行以下操作来保持抽象干净:
services.AddTransient<FooConcrete>();
services.AddScoped<DisposableFoo>();
services.AddScoped<IFoo>(ctx => ctx.Resolve<DisposableFoo>.Instance);
在这种情况下,基础FooConrecte
将在范围生存期结束时正确释放。