Hi this is in relation to a previous question of mine.
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>();
}