gpt4 book ai didi

c# - Service owns disposable Repository that owns disposable DbContext - Dispose IDisposables injected with Unity

转载 作者:太空宇宙 更新时间:2023-11-03 19:59:15 27 4
gpt4 key购买 nike

我有一个服务、一个存储库和一个 DbContext。存储库拥有 DbContext,服务拥有存储库。

我的存储库应该实现 IDisposable 吗?如果是这样,我的服务是否也应该实现 IDisposable 并处置存储库?

我想一个更普遍的问题可能是,如果我有一个类引用了一个类,它引用了另一个类,......(等等)......,它引用了非托管或托管的一次性资源 - 它们是否应该全部实现IDisposable

最佳答案

Unity DI 无法在对象的生命周期结束时处置对象,并且在 GC 决定收集它们之前您不能将它们留在那里。

理论上有实现Register/Resolve/Release的DI框架,Release是调用dispose的地方,但Unity没有实现Release部分。我不知道在 .NET 中是否有其他框架可以做到这一点。

使用 Unity,有两种解决方案:

1) 简单的技巧

不要注入(inject)DbContext,而是在需要的地方从容器中解析它,这样你就可以控制它的处置

using(var ctx = container.Resolve<MyDbContext>())
{
}

警报!警报!服务定位器反模式

2) 智能解决方案

注入(inject)一个可以在您需要时为您提供 DbContext 的工厂。如果您这样做,而不是注入(inject) DbContext,而是注入(inject)一个可以在您需要时为您提供 DbContext 的类:一个工厂。您可以在 DI 容器中将您的工厂注册为单例,因为您将持续使用它

using(var ctx = DbContextFactory.GetContex())
{
}

您的工厂可能看起来像这样:

public class DbContextFactory : IDbContextFactory
{
public DbContext GetDbContext()
{
...
}
}

这样它就可以通过构造函数注入(inject)来注入(inject):

public MyService(IDbContextFactory dbContextFactory)
{
}

而且,如前所述,没有理由不将其注册为单例:您可以安全愉快地使用同一个工厂来构建大量 Db 上下文!

注意:如果你使用一个抽象工厂会更好,它不是返回具体对象而是返回一个接口(interface)实现,这是一个小小的改变

public class DbContextFactory : IDbContextFactory
{
public IDbContext GetDbContext()
{
...
}
}

您可以阅读此内容以获取更多信息和示例:

关于c# - Service owns disposable Repository that owns disposable DbContext - Dispose IDisposables injected with Unity,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30081540/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com