繁体   English   中英

使用 DI 和 UoW 模式时是否需要使用 EF 语句

[英]Do i need using statements for EF when utilising DI and UoW patterns

在许多基本示例中,我看到 using 块环绕着DbContext用法,如下所示:

using (var context = new MyDbContext()) 
{     
    // Perform data access using the context 
}

这是有道理的,因为正在创建一个“新”实例,因此您希望在完成后处理它。

使用 DI

但是,在我正在处理的许多项目中,我看到DbContext被注入到存储库和服务层中,如下所示:

public class FileRequestService : IFileRequestService
{
    private readonly MyDbContext _myDbContext;

    public FileRequestService(MyDbContext myDbContext)
    {
        _myDbContext = myDbContext;
    }

    public FileRequest SaveFileRequest(FileRequest fileRequest)
    {
        fileRequest.Status = FileRequestStatus.New;
        //...
        //...
        var fr = _myDbContext.FileRequests.Add(fileRequest);
        _myDbContext.SaveChanges();
        return fr;
    }
}

并在 DI 容器中配置如下:

container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();

container.Register<MyDbContext>(Lifestyle.Singleton);

问题 1

这里没有使用 using 语句是否可以,因为一旦 Web 请求终止,它可能会被处理掉?

使用 DI/UoW

工作单元模式的类似场景,我看到了这个:

public class RecordController : Controller
{
  private readonly IUnitOfWork _unitOfWork;

  public RecordController(IUnitOfWork unitOfWork)
  {
      _unitOfWork = unitOfWork;
  }

  [HttpPost, ActionName("Index")]
  public PartialViewResult Search(SearchQueryViewModel searchQueryViewModel)
  {    
      var deptId =
      _unitOfWork.DepartmentRepository.Get(x => x.DepartmentCode == searchQueryViewModel.code)
      .Select(s => s.DepartmentId)
      .FirstOrDefault();
       //...                
   }
}

在容器中配置如下:

container.Register<IUnitOfWork, UnitOfWork>(Lifestyle.Scoped);
container.Register<IGenericRepository<Department>, GenericRepository<Department>>(Lifestyle.Scoped);

并且DbContext被注入到 UoW 类的构造函数中。

问题2

同样,这里没有使用 using 语句是否可以,或者我应该在 UoW 类上实现IDisposable接口并执行以下操作:

using (_unitOfWork)
{    
  var deptId =
  _unitOfWork.DepartmentRepository.Get(x => x.DepartmentCode == searchQueryViewModel.code)
  .Select(s => s.DepartmentId)
  .FirstOrDefault();
  //...
}

简单地说,谁创建了一个实例,谁就应该负责调用它的 dispose 方法。

关于问题 1:我个人会避免对 DbContext 使用单例。 谷歌上的快速搜索显示了许多文章/Stackoverflow 问题,但这是第一个: 单例中的实体框架上下文在您当前的情况下 - 它不会被处理,永远不会。 它在单例范围中注册,这意味着您将拥有一个与容器一样长的实例。 (简单的注入器范围帮助页面供参考 - http://simpleinjector.readthedocs.io/en/latest/lifetimes.html

关于问题 2:大多数容器一旦离开其作用域,就会调用所有 IDisposable 实例的 dispose 方法。 如果您早些时候调用 dispose 自己,您可能最终会在其他地方处理将作为依赖项提供的实例。 这样做将导致其他代码尝试使用相同的已处理实例...

编辑:如果范围不受 DI 框架控制,您当然必须自己调用 dispose 。 但这不是我们正在讨论的情况

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM