Domanda

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?

È stato utile?

Soluzione

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top