gpt4 book ai didi

c# - 我们真的需要在 Repository 或 UnitOfWork 类中实现 IDisposable 吗?

转载 作者:行者123 更新时间:2023-11-30 14:05:44 24 4
gpt4 key购买 nike

首先,让我们看看微软对 Asp.Net Core 的默认依赖注入(inject)服务是怎么说的:

The framework takes on the responsibility of creating an instance of the dependency and disposing of it when it's no longer needed.

https://learn.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-2.1#disposal-of-services

即该框架将调用一个类 Dispose 方法(假设该类实现了 IDisposable)

其次,DbContext 类确实实现了开箱即用的 IDisposable。

第三,在我们的 Startup.cs 类中,我们通过 AddDbContext 方法添加我们的 DbContext,默认情况下它被添加为 Scoped 实例(即我们的 DbContext 是在每个请求上创建和垃圾收集的).

Scoped lifetime services are created once per request.

https://learn.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-2.1#service-lifetimes

例如

public void ConfigureServices(IServiceCollection services)
{
services
.AddDbContext<TheStoreDbContext>(ConfigureDbContext)
.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
}

结论,我们不需要在我们的 Asp.net Core 应用程序中的任何地方显式调用 context.Dispose()。

那么,为什么网上和教程中有那么多示例向您展示必须在 Repository 或 UnitOfWork 类中实现 IDisposable?

例如

public class UnitOfWork : IUnitOfWork
{
private readonly DbContext _context;

public IProductRepository ProductRepository { get; }

public UnitOfWork(DbContext context)
{
_context = context;
ProductRepository = new ProductRepository(context);
}

public void Dispose()
{
_context.Dispose();
}
}

你怎么看?这是一个有效的问题吗?不在任何地方显式调用 Dispose() 方法是否有意义?

最佳答案

根据经验,一个类应该只处理它拥有的。但是,对于 UnitOfWork,它不拥有 DbContext,因为它不是由 UnitOfWork 创建的>——而是由其他人从外部提供。

UnitOfWork 处理那个 DbContext 甚至会产生问题,因为 UnitOfWork 无法知道 DbContext 在处理 UnitOfWork 时仍由系统中的其他类使用。换句话说,当 UnitOfWork 开始处理该依赖项时,应用程序可能会中断。

因此,如果您遵循仅处置您拥有的的规则,这意味着 UnitOfWork 实际上应该 实现 IDisposable 完全没有。这意味着您让“其他人”控制 DbContext 的生命周期。

这种将依赖项(例如 DbContext)的生命周期控制权移交给第三方的想法并不是什么新鲜事,当然也不是新的 Microsoft DI 容器所特有的。这其实是一个古老的想法,就是你把对应用程序组件生命周期的控制权集中在应用程序的启动路径上。在 DI 的上下文中,此启动路径通常称为 Composition Root .

在 Composition Root 中,Composer 的工作是创建应用程序组件,管理它们的生命周期,并在不再需要它们时处理它们。 DI 容器(如 .NET Core DI 容器)充当系统中的 Composer,但您也可以手动执行此操作——通常称为 Pure DI 的做法.

另见 this answer ,其中还谈到了在 SOLID 原则的背景下进行处置。

关于c# - 我们真的需要在 Repository 或 UnitOfWork 类中实现 IDisposable 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54417593/

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