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

问题描述 投票:0回答:1

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

框架负责创建依赖项实例并在不再需要时将其处置。

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 在每个请求上创建并进行垃圾收集)。

每个请求都会创建一次范围内的生命周期服务。

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() 方法是否有意义?

c# asp.net-core dependency-injection unit-of-work
1个回答
20
投票

经验法则是,一个类应该只处理它拥有的。然而,就您的

UnitOfWork
类而言,它并不 拥有
DbContext
,因为它不是由
UnitOfWork
创建的,而是由“其他人”从外部提供。

DbContext

处理

UnitOfWork
甚至可能会产生问题,因为当
DbContext
被处理时,
UnitOfWork
无法知道系统中的其他类是否仍在使用
DbContext
。换句话说,当
UnitOfWork
开始处理该依赖项时,应用程序可能会中断。
因此,如果您遵循仅处置您

拥有的

的规则,则意味着UnitOfWork实际上应该

实施UnitOfWork。这意味着您让“其他人”控制
IDisposable
的生命周期。
将依赖项生命周期的控制权(例如

DbContext

)转移给第三方的想法并不是什么新鲜事,当然也不是新的 Microsoft DI 容器特有的东西。这实际上是一个古老的想法,即在应用程序的启动路径中集中控制应用程序组件的生命周期。在 DI 上下文中,此启动路径通常称为

Composition Root
在组合根内部,

Composer

的工作是创建应用程序组件、管理它们的生命周期,并在不再需要它们时将其丢弃。 DI 容器(如 .NET Core DI 容器)充当系统中的 Composer,但您也可以手动完成此操作,这种做法通常称为“纯 DI”。 另请参阅这个答案,其中也谈到了在 SOLID 原则的背景下进行处置。

© www.soinside.com 2019 - 2024. All rights reserved.