EF DbContext Factory with Ninject C#

本文关键字:Ninject with Factory DbContext EF | 更新日期: 2023-09-27 18:16:32

我正在寻找一些关于重构我所编写的现有c#控制台应用程序的最佳方法的建议。应用程序利用实体框架与存储库模式相结合的数据。我也使用Ninject的DI。我面临的问题如下:

我有一个类,比如ClassA,它有一个通过构造函数传入的Repository。存储库构造函数接受一个DbContext。Ninject目前正在为我处理所有这些。

public class ClassA
{
  private IRepository Repository;
  public ClassA(IRepository repostitory)
  {
    Repository = repository;
  }
  public void Process()
  {
    var RV = Function1();
    Function2(RV);
    Function3(RV);
  }
  private IList<ClassB> Function1()
  {
    //Populate database using Repository and return list of objects
    var items = //Call External Web Service to get list of Items
    foreach(var item in items)
    {
      Repository.AddEntry(item);
    }
    return Repository.Items.ToList();
  }
  private void Function2(IList<Item> items)
  {
    //Long running process maybe 20/30 mins.
  }
  private void Function3(IList<Item> items)
  {
    //Remove objects in list from database via the Repository.
    foreach(var item in items)
    {
      Repository.DeleteEntry(item);
    }
  }
}
public class Repository : IRepository
{
  private DbContext DbContext;
  public IQueryable<Item> Items
  {
    get { return DbContext.Items; }
  }
  public Repository(DbContext dbContext)
  {
    DbContext = dbContext;
  }
  void AddEntry(Item item)
  {
    DbContext.Items.Add(item);
    DbContext.SaveChanges();  
  }
  void DeleteEntry(Item item)
  {
    DbContext.Items.Remove(item);
    DbContext.SaveChanges();
  }
}

ClassA有一个进程函数,它通过一系列3个私有函数工作。

只有函数1和3需要访问Repository,因为函数1通过Repository填充数据库,然后返回一个内存集合。函数2使用这个集合,然后函数3通过Repository从数据库中删除记录。

函数2可能需要几分钟才能完成,我注意到的行为是,当函数3调用数据库时,我收到一个"DbContext已被处置"错误。它没有在我的任何代码中被处理,但似乎在同一SQL服务器上运行的另一个进程正在导致这种情况。

为了解决这个问题,我希望能够在函数1之后处理存储库,然后为函数3使用一个新的存储库,所以本质上把代码包装在函数1 &3在using语句中。当我试图在使用Ninject时弄清楚这个场景时,我的头开始疼了。

我应该传递给ClassA作为构造函数的一部分,以允许我创建动态存储库?我是否需要某种工厂模式或工作单元模式?

任何帮助或想法都非常感谢。

感谢

pf79

EF DbContext Factory with Ninject C#

您可以将DbContext作为工厂而不是实例注入,看看这个:https://github.com/vany0114/EF.DbContextFactory

http://elvanydev.com/EF-DbContextFactory/

Ninject有一个扩展,可以很容易地做到这一点,只需调用kernel.AddDbContextFactory<YourContext>();方法,您还需要通过接收Func<YourContext>来更改存储库