EF DbContext and Ninject
-
26-10-2019 - |
Pergunta
I asked a question a while back about why the default equality comparer didn't seem to work when I was union two collections of entities.
EF Code First - Linq to Entities Union EqualityComparer
The answer was due to the fact that I was using two difference instances of my DbContext hence different references.
So now I am trying to share my DbContent across the request. I see a few "complicated" examples but I thought I'd try for a more simple solution.
So I created a IDbContext interface which simply outlines my Entities
public interface IDbContext {
int SaveChanges();
DbSet<News> News { get; set; }
DbSet<Category> Categories { get; set; }
}
My DbContext is then implement like this:
public class SiteContext : DbContext, IDbContext {
public DbSet<News> News { get; set; }
public DbSet<Category> Categories { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
...
}
}
Then in my two repositories (NewsRepository and CategoryRespository) I have the IDbContext as a constructor parameter
IDbContext _db;
public NewsRepository(IDbContext db) {
_db = db;
}
So now I assume that if I bind IDbContext to SiteContext in the request scope my repositories will share the same context?
kernel.Bind<IDbContext>().To<SiteContext>().InRequestScope();
However, when I try my union again from the previous question I still receive duplicate entities! What I am doing wrong? How can I tell if I am definitely using the same context in one request?
Solução
Because when each repository is constructed Ninject will is providing you with a new instance of SiteContext per repository. Thats why its not working. Its a good idea to use a unitofwork implementation which means all repositories use the same context.
The UnitOfWork would take in a IDbContext on construction.
Some thing like this would work
private IDbContext _context;
public UnitOfWork(IDbContext context)
{
_context = context
}
private _INewsRepository;
public INewsRepoitory
{
get{
if(_INewsRepository == null)
{
_INewsRepository = new NewsREpository(_context);
return _INewsRepository;
}
else
{
return _INewsRepository;
}
}
Outras dicas
To improve the solution of feanz I would still do property injection of the INewsRepository with Ninject:
[Inject]
public INewsRepository NewsRepo {get;set;}
Every time an IUnitOfWork is created there is also an INewsRepository created. This must still be added to your ninject bindings.