LanFeusT
LanFeusT

Reputation: 2432

MVC3 tool using Entity Framework caching issues with Ninject

I've got a new MVC 3 application which is showing some issues when modifying data manually in the Database.

The tool is still in development and once in a while I want to change my user's teamId. When I do so, I have to kill the Web development Server and run it again otherwise the queries don't pick the new teamId. Same thing when I publish the tool to IIS, if I ever modify something on the database, I need to either copy over the 'bin' folder again or stop the application and re-run it.

When I modify data from the application itself, I have no problems.

This is how my Ninject looks like:

public class NinjectControllerFactory : DefaultControllerFactory
{
    private IKernel kernel = new StandardKernel(new TrackerServices());

    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
    {
        if (controllerType == null)
            return null;
        return (IController)kernel.Get(controllerType);
    }

    private class TrackerServices : NinjectModule
    {
        public override void Load()
        {
            var context = new TrackerEntities();

            Bind<IUserRepository>().To<UserRepository>().WithConstructorArgument("context", context);
        }
    }
}

My Interface:

public interface IUserRepository : IRepository<User>
{
    User GetByName(string name);
}

my Implementation:

public User GetByName(string login)
{
    var userLogin = _misc.GetUsername(login);
    return _context.Users.Where(x => x.Login == userLogin).Single();
}

And my Index Action

public ActionResult Index()
{
    var teamid = (int)_users.GetByName("myName").TeamId;

This has never happened before, but this tool is the first one I'm using with Ninject. I'm wondering if there's a relation between my problem and using a repository?

Upvotes: 1

Views: 618

Answers (1)

Bennor McCarthy
Bennor McCarthy

Reputation: 11675

There are two issues that are combining to create this problem:

  1. The way you've created your context is causing it to effectively be a singleton.
  2. Entity Framework will not automatically check for a new version of an entity which the context is already tracking.

To solve this, I would recommend that you recreate your repository once per request (there won't be a significant performance hit for this, as it's fairly lightweight), by using this binding:

Bind<IUserRepository>().To<UserRepository>().InRequestScope();

Ninject should be able to create your TrackerEntities context automatically, but if not (or if you want to make it clear), you can use the following binding:

Bind<TrackerEntities>().ToSelf().InRequestScope(); (The InRequestScope is not really required here, as the default transient scope should be okay).

You could also go down the road of forcing a refresh of the entity (using ObjectContext.Refresh()), but that's probably not a great idea because you'd have to do it explicitly for each entity.

Upvotes: 3

Related Questions