Reputation: 4607
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 protected]"
}, _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?
Upvotes: 2
Views: 1153
Reputation: 172676
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.
Upvotes: 3