Search code examples
entity-frameworksingletonstructuremapdisposedbcontext

Disposing entity framework dbcontext in singleton class (StructureMap)


In my application i am using StructureMap with EntityFramework.

Well, my ioc config looks like :

x.For<IDbContext>().Use(c => new DbContext(AppSettings.ConnectionString));
x.For<IManager>().Singleton().Use<DefaultManagerImplementation);
x.For<IManagerService>().Use<DefaultManagerServiceImplementation>();

My problem is about disposing DbContext instance, which one is use in IManagerService.

IManagerService :

using(var ctx = new DbContext(AppSettings.ConnectionString)
{
   // works fine
   ctx. 
   ctx.save();
}


public class ManagerService : IManagerService
{
   private readonly IDbContext _dbContext;

   public ManagerService(IDbcontext dbContext)
   { 
      // not works, because DbContext is not disposed? 
      _dbContext = dbContext; // inject
      ...
      _dbContext.Get... return old data 
   }
}

Well, is here any change to force dispose object which lives in singleton instance in structure map?

Thanks


Solution

  • You won't get any automatic disposing of this object because as far as your container is concerned, you're still using it. There are two options here:

    1. Explicitly call .Dispose() on the DbContext when you're finished with it. You won't be able to use the DbContext anywhere else within your Singleton, since the object is now gone.

    2. Instead of taking a dependency on DbContext, take a dependency on Func<DbContext> (or some other factory interface). I'm not sure about StructureMap, but other IoC containers handle Func automatically as long as you've registered T, so this shouldn't need any new dependencies. This would change your constructor to the following:

      public class ManagerService : IManagerService
      {
         private readonly Func<IDbContext> _dbContextFactory;
      
         public ManagerService(Func<IDbContext> dbContextFactory)
         { 
             _dbContextFactory = dbContextFactory; // inject
             using (var context = _dbContextFactory())
             {
                ...
                 // Do stuff with your context here
             } // It will be disposed of here
      
             using (var context = _dbContextFactory()) 
             {
                // ...and here's another context for you
             }
         }
      }