Question

I am using StructureMap as my IOC Container. I created a seed method that runs on start-up, to be sure the database has relevant data. When this runs, i get the error

The operation cannot be completed because the DbContext has been disposed.

The seed class in question is

public class SeedDatabase : IRunAtStartup
{
    private DbContext _context;
    private UserManager<ApplicationUser> _userManager;
    public SeedDatabase(DbContext context, UserManager<ApplicationUser> userManager)
    {
        _context = context;
        _userManager = userManager;
    }

    public async void Execute()
    {
        if (!_context.Set<ApplicationUser>().Any())
        {
            //Seed Admin User
            await _userManager.CreateAsync(new ApplicationUser
                  {
                     UserName = "Admin",
                     Company = "Test Company Ltd",
                     EmailAddress = "email@emailaddress.com"
                  }, _userManager.PasswordHasher.HashPassword("Password"));

           _context.SaveChanges();
        }
    }
}

The error occurs on hitting .SaveChanges()

This method just runs once at startup and it accepts a UserManager and DbContext in its conctructor which are provided by means of the IOC Container.

I have tried handling the DbContext per HttpRequest, which was my preference, but also as a singleton. However, the situation did not change.

Here is some of the setup for IOC Container

//convention for DbContext
public class DbContextConvention : IRegistrationConvention
{
     public void Process(Type type, Registry registry)
     {
         //be sure a new context is used for each request
         if (type.CanBeCastTo(typeof(DbContext)) && !type.IsAbstract)
         {
            registry.For(type).LifecycleIs(new UniquePerRequestLifecycle());
         }
     }
}

Any ideas why I keeps disposing it before it has even been used?

Was it helpful?

Solution

The problem is probably caused by the asynchronous nature of your Execute method. This method will return almost immediately and will continue on a background thread. You are probably disposing the DbContext after Execute returned, but at that moment in time the background operation hasn't finished. Instead, return a Task and wait for that task to finish before cleaning up, or make the Execute method synchronous.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top