3

I have an ASP.NET mvc3 application which is using ninject for DI. The app is making use of Entity Framework 4 and a database initializer that also seeds custom data into the db.

The database initializer runs in HttpApplication.Application_Start.

However I get an error because it seems that the child request is called before the database initializer finished creating and seeding the db:

The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.

My _layout.cshtml has some child request:

@Html.Action("Present", "Time")

That it:

[ChildActionOnly]
public ActionResult Present()
{
    //HttpContext.Trace.Write("Inside [ChildActionOnly]\npublic ActionResult Present() (child requests that is called by _layout.cshtml)");
    System.Diagnostics.Debugger.Launch();
    Employee employee = this.employeeService.CurrentEmployee;

However once the database is successfully created and seeded with my database initializer called "EFZeiterfassungDataContextInitializer" (it inherits from DropCreateDatabaseIfModelChanges) the app is working.

I'm only having this problem with the first (child) request!

In my ninject module I configured my datacontext (called EFZeiterfassungContext) like this:

Bind<EFZeiterfassungContext>().ToSelf().InRequestScope();

Some more info:

Here is some code of my HttpApplication:

public void SetupDependencyInjection()
{
    // Create Ninject DI Kernel 
    IKernel kernel = new StandardKernel(new ZeiterfassungNinjectModule());
    //Tell asp.net mvc  to use our ninject di container
    DependencyResolver.SetResolver(new NinjectDependencyResolver(kernel));
}

protected void Application_Start()
{
    SetupDependencyInjection();
    AreaRegistration.RegisterAllAreas();
    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);
    InitializeDatabase();
}

private void InitializeDatabase()
{
    IActiveDirectoryService adService = DependencyResolver.Current.GetService<IActiveDirectoryService>();
    IEmployeeService employeeService = DependencyResolver.Current.GetService<IEmployeeService>();
    EFZeiterfassungDataContextInitializer d = new EFZeiterfassungDataContextInitializer(
        Server.MapPath("~/Content/UserImages/"),
        adService,
        employeeService);
    Database.SetInitializer<EFZeiterfassungContext>(d);
}

EDIT + workaround:

Obviously Database.SetInitializer(d); returns immediately. the initializer isn't run immediately - not even async. EF first checks the DB for changes if you have some interaction with the datacontext i.e. by querying some value from the not yet existing db. I could workaround it by calling var currentEm = employeeService.GetById(1); after Database.SetInitializer(d);. so the DB really gets initialized on application_start and not later.

I would like to see some overloaded method of SetInitializer so you can immediately trigger that process.

I'm still interested in a better solution for this until SetInitializer has such an overloaded method.

toebens
  • 4,039
  • 6
  • 24
  • 31
  • See http://stackoverflow.com/questions/4363230/ninject-bind-should-be-inrequestscope-or-insingletonscope and http://stackoverflow.com/questions/5687355/need-help-understanding-how-ninject-is-getting-a-nhibernate-sessionfactory-instan – Ruben Bartelink Jun 16 '11 at 05:26
  • 1
    i've re-written the question as it seems that the child request is processed before the database initializer finished creating and seeding the db – toebens Jun 16 '11 at 08:54
  • i think, that initialiser dispose context and you try to use this disposed context – vlukham Jun 23 '14 at 11:14
  • example for autofac. what if you make var context = DependencyResolver.Current.GetService(); context.Database.Initialize(true); after Database.SetInitializer – vlukham Jun 23 '14 at 12:59

0 Answers0