How to manage a DbContext lifetime using the Ninject MVC extension

Hi this is in relation to a previous question of mine.

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

I am unsure of how I can implement the use of my DbContext correctly when using Ninject & MVC based on the reference given in the answer to my previous question. Does anyone have a recommended example of how this should be done? thanks.

I did see this 1 example here: How to handle DBContext when using Ninject but I wasn't sure how this could fit into the current structure of my project.

Here is an example of one of my repositories and the interface, the other repositories are pretty much identical and at the moment all create a new context, I will likely change this to inject the context into the repository but I dont think this will be enough.

public interface IRepository<T> where T : Entity {
    IQueryable<T> All { get; }
    T Find(int id);
    void InsertOrUpdate(T entity);
    void Delete(int id);
    void Save();
}

public class RecipeRepository : IRepository<Recipe>
{

    private EatRateShareDbContext context = new EatRateShareDbContext();

    public IQueryable<Recipe> All
    {
        get { return context.Recipes; }
    }

    public Recipe Find(int id)
    {
        return context.Recipes.Find(id);
    }

    public void InsertOrUpdate(Recipe recipe)
    {
        if (recipe.Id == default(int))
        {
            // New entity
            context.Recipes.Add(recipe);
        } else
        {
            // Existing entity
            context.Entry(recipe).State = EntityState.Modified;
        }
    }

    public void Delete(int id)
    {
        var recipe = context.Recipes.Find(id);
        context.Recipes.Remove(recipe);
    }

    public void Save()
    {
        try
        {
            context.SaveChanges();
        }

        catch (DbEntityValidationException databaseException)
        {
            foreach (var validationErrors in databaseException.EntityValidationErrors)
            {
                foreach (var validationError in validationErrors.ValidationErrors)
                {
                    Trace.TraceInformation("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage);
                }
            }
        }


    }
}

This is my DbContext

public class ERSDbContext : DbContext
{
    public DbSet<Recipe> Recipes { get; set; }
    public DbSet<Ingredient> Ingredients { get; set; }
    public DbSet<Review> Reviews { get; set; }
    public DbSet<Course> Courses { get; set; }
    public DbSet<Cuisine> Cuisines { get; set; }
    public DbSet<Member> Members { get; set; }
    public DbSet<Step> Steps { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        // have to specify these mappings using the EF Fluent API otherwise I end up with
        // the foreign key fields being placed inside the Recipe and Member tables, which wouldn't
        // give a many-to-many relationship
        modelBuilder.Entity<Recipe>()
            .HasMany(r => r.Members)
            .WithMany(m => m.Recipes)
        .Map(x => {
            x.ToTable("Cookbooks"); // using a mapping table for a many-to-many relationship
            x.MapLeftKey("RecipeId");
            x.MapRightKey("MemberId");
        });

        modelBuilder.Entity<Recipe>()
            .HasRequired(x => x.Author)
            .WithMany()
            .WillCascadeOnDelete(false);

    }
}

I use Ninject to inject my repositories into the controller as shown

    public class RecipesController : Controller
    {
        private readonly IRepository<Member> memberRepository;
        private readonly IRepository<Course> courseRepository;
        private readonly IRepository<Cuisine> cuisineRepository;
        private readonly IRepository<Recipe> recipeRepository;

        public RecipesController(IRepository<Member> memberRepository, IRepository<Course> courseRepository, IRepository<Cuisine> cuisineRepository, IRepository<Recipe> recipeRepository)
        {
            this.memberRepository = memberRepository;
            this.courseRepository = courseRepository;
            this.cuisineRepository = cuisineRepository;
            this.recipeRepository = recipeRepository;
        }
...
}

For Ninject I am using the Nuget plugin which creates a NinjectWebCommon class and the below are my current bindings.

    private static void RegisterServices(IKernel kernel)
    {
        kernel.Bind<IRepository<Recipe>>().To<RecipeRepository>();
        kernel.Bind<IRepository<Member>>().To<MemberRepository>();
        kernel.Bind<IRepository<Cuisine>>().To<CuisineRepository>();
        kernel.Bind<IRepository<Course>>().To<CourseRepository>();
        kernel.Bind<IRepository<Review>>().To<ReviewRepository>();
    }      

Answers


I found this related post http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application

which best answered how to do the implementation by using a unit of work and a more generic repository.

I still need to clean this up to work with Ninject but i am answering my question so I can close this now.


Need Your Help

Symfony 2 StofDoctrineExtensionBundle timestampable with odm (MongoDB)

mongodb symfony2 doctrine2

I tried using the timestampable behavior from StofDoctrineExtenstion for my object, but it doesn't work. Object is saved successfully, but createdAt property isn't saved.

Open dialog instead of alert/prompt in jquery

javascript jquery events dialog fullcalendar

I am using fullcalendar. I would like to show a dialog when I click on an event. But I only know how to pop up an alert or prompt. How do I popup a dialog with JavaScript?

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.