Major Productions
Major Productions

Reputation: 6042

Ninject MVC 2 - problems with EF 4 ObjectContext

I've been dealing with this issue for a while, and still can't seem to find a solution. I have several repositories which wrap an EF 4 ObjectContext. An example is below:

public class HGGameRepository : IGameRepository, IDisposable
{
    private readonly HGEntities _context;

    public HGGameRepository(HGEntities context)
    {
        this._context = context;
    }

    // methods

    public void SaveGame(Game game)
    {
        if (game.GameID > 0)
        {
            _context.ObjectStateManager.ChangeObjectState(game, System.Data.EntityState.Modified);
        }
        else
        {
            _context.Games.AddObject(game);
        }

        _context.SaveChanges();
    }

    public void Dispose()
    {
        if (this._context != null)
        {
            this._context.Dispose();
        }
    }
}

And I have the following NinjectModule:

public class DIModule : NinjectModule
{
    public override void Load()
    {
        this.Bind<HGEntities>().ToSelf();
        this.Bind<IArticleRepository>().To<HGArticleRepository>(); 
        this.Bind<IGameRepository>().To<HGGameRepository>();
        this.Bind<INewsRepository>().To<HGNewsRepository>();
        this.Bind<ErrorController>().ToSelf();
    }
}

Since I'm using the MVC 2 extension, these bindings default to InRequestScope().

My problem is that the ObjectContext isn't being handled properly. I get what's described here: https://stackoverflow.com/a/5275849/399584 Specifically, I get an InvalidOperationException that states:

The relationship between the two objects cannot be defined because they are attached to different ObjectContext objects.

This happens every time I try to update an Entity.

If I set my repos to bind InSingletonScope() it works, but seems like a bad idea.

What am I doing wrong?

EDIT: For clarity, I have just one ObjectContext that I want to share with all my repos per request.

Upvotes: 0

Views: 434

Answers (1)

bytebender
bytebender

Reputation: 7491

You have to specify InRequestScope() in your module. Based on this article the default to transient, which is why you are getting more than one context.

public class DIModule : NinjectModule
{
    public override void Load()
    {
        this.Bind<HGEntities>().ToSelf().InRequestScope();
        this.Bind<IArticleRepository>().To<HGArticleRepository>().InRequestScope(); 
        this.Bind<IGameRepository>().To<HGGameRepository>().InRequestScope();
        this.Bind<INewsRepository>().To<HGNewsRepository>().InRequestScope();
        this.Bind<ErrorController>().ToSelf().InRequestScope();
    }
}

Also did you add ninject to your project via nuget package manager or the old fashion way?

Upvotes: 1

Related Questions