ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2019-10-24 21:05:54  阅读:461  来源: 互联网

标签:unit-of-work asp-net-core dependency-injection c


首先,让我们看看微软对Asp.Net Core的默认依赖注入服务的看法:

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

https://docs.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://docs.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类示例实际上是一种不好的做法.规则是,一个类只能处置其拥有的东西.但是,对于UnitOfWork,它不拥有DbContext,因为它不是由UnitOfWork创建的,而是由其他人提供的.

让UnitOfWork处置该DbContext甚至是有问题的,因为在处置UnitOfWork时,UnitOfWork无法知道系统中的其他类是否仍在使用DbContext.换句话说,当UnitOfWork开始处理该依赖项时,系统可能会中断.

因此,如果遵循只处理自己拥有的东西的规则,则意味着UnitOfWork实际上根本不应该实现IDisposable.这意味着您让“其他人”控制DbContext的生存期.

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

在“合成根目录”内部,Composer的工作是创建应用程序组件,管理它们的生命周期并在不再需要它们时进行处理. DI容器(如.NET Core DI容器)在您的系统中充当Composer,但是您也可以手动完成此操作-这种做法通常称为Pure DI.

标签:unit-of-work,asp-net-core,dependency-injection,c
来源: https://codeday.me/bug/20191024/1923381.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有