Search code examples
c#asp.net-mvcentity-frameworkdependency-injectionninject

Singleton Scope for EF's DbContext


so I am currently working on an ASP.NET MVC web application that uses Entity Framework, I'm also using Ninject for Dependency Injection.

So basically, at the moment, this is how I register my DbContext and Services with Ninject.

kernel.Bind<DbContext>().To<MyApplicationContext>().InSingletonScope();
kernel.Bind<IAccountService>().To<AccountService>().InSingletonScope();
kernel.Bind<IRegionService>().To<RegionService>().InSingletonScope();
kernel.Bind<IRoleService>().To<RoleService>().InSingletonScope();

I register them with InSingletonScope, which means that they will only be created once and used throughout the lifetime of the application (at least how I understand it).

Controllers:

private IAccountService _accountService;

public MemberController(IAccountService accountService)
{
    _accountService = accountService;
}

However, I have a deep feeling that this singleton scope will cause problem in my web application especially for the Entity Framework's context, due to it being singleton.

I am already facing a minor issue due to this, if I manually update the database using SQL Management Studio, the data in my web application's Entity Framework wouldn't update until I restart the application (seems to be some caching mechanism in EF).

--

However, if I remove the InSingletonScope, I will randomly get errors from EF saying that:

An entity object cannot be referenced by multiple instances of IEntityChangeTracker

I understand why this happens because the DbContext initialized by AccountService could be different from say, RegionService. But I have no idea how I can resolve this.

My understanding of Dependency Injection is still very limited, so can anybody please advice?

--

EDIT: I've tried changing to InRequestScope for all the injections, but I'm still getting

An entity object cannot be referenced by multiple instances of IEntityChangeTracker

When trying to insert a new entity with related object (foreign key) from another service in my application. That means they are still using a different DbContext, what is happening?!

FINAL EDIT: Ok I've found the problem, it was my caching mechanism that was caching a previous request, causing the relationship issue on all subsequent request.


Solution

  • I've finally managed to resolve this issue by using InRequestScope instead of InSingletonScope.

    Initially, I was still facing the same problem after changing to InRequestScope because of my existing caching mechanism on my services layer.

    Thus, all subsequent requests were using the initially-cached entity object, that was why I was getting multiple instances error from EF.

    --

    If you are still facing the

    An entity object cannot be referenced by multiple instances of IEntityChangeTracker

    error after changing to InRequestScope, make sure your entities are not somehow cached or stored for subsequent HTTP requests uses.