pf79
pf79

Reputation: 86

EF DbContext Factory with Ninject C#

I am looking for some advice on the best way to re-structure an existing C# Console Application that I have written. The application utilises Entity Framework for the Data coupled with the Repository pattern. I am also using Ninject for DI. The issue I am facing is as follows:

I have a class, say ClassA, which has a Repository passed in through the constructor. The repository constructor takes in a DbContext. Ninject is currently handling all of this for me.

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 then has a process function that works through a series of 3 private functions.

Only functions 1 and 3 need access to the Repository, as 1 populates the database via the Repository and then returns an in memory collection. Function 2 uses this collection, after which function 3 deletes records from the database via the Repository.

Function 2 can take several minutes to complete and the behaviour I am noticing is that when function 3 calls the database I receive a "DbContext has been disposed" error. It has not been disposed in any of my code but it seems another process running on the same SQL server is causing this.

In an attempt to work around this I want to be able to dispose of the Repository after function 1 and then use a new one for function 3, so in essence wrap the code in function 1 & 3 inside a using statement. This is when my head starts to hurt when trying to figure out this scenario whilst utilising Ninject.

What should I be passing in to ClassA as part of the constructor to allow me to create on the fly Repostitories? Do I need some sort of Factory pattern or Unit of Work pattern?

Any help or thoughts gratefully received.

Thanks

pf79

Upvotes: 1

Views: 2042

Answers (1)

You can inject your DbContext as a factory instead of an instance perse, take a look at this: https://github.com/vany0114/EF.DbContextFactory

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

There is an extension to Ninject to do that in a very easy way, just calling the method kernel.AddDbContextFactory<YourContext>(); also you need to change your repository by receiving a Func<YourContext>

Upvotes: 1

Related Questions