MVC Code First 和具有复杂映射的 Ninject 缓存
我的问题与此非常相似: MVC3 tool using Entity Framework Ninject 的缓存问题 但是我的映射有点复杂,当我使用 InRequestScope
时,我收到以下错误:
由于 DbContext 已被释放,操作无法完成。
如果我不包含 InRequestScope
,除了 EF Code First 似乎会缓存我的实体并且它与数据库中的值不匹配之外,一切都会正常工作。
这是我的 ninject 映射,我正在使用 ninject mvc3 nuget 包(没有 InRequestScope
):
kernel.Bind<MyContext>()
.ToSelf()
.WithConstructorArgument("connectionString", context => MvcApplication.GetConnectionStringName);
kernel.Bind<IUnitOfWork>().To<UnitOfWork>();
// Service Layer.
kernel.Bind<ICustomerService>().To<CustomerService>();
kernel.Bind<IMessageService>().To<MessageService>();
kernel.Bind<IUserService>().To<UserService>();
// Repository Layer.
kernel.Bind<IRepository<Customer>>().To<GenericRepository<Customer>>();
kernel.Bind<IRepository<Message>>().To<GenericRepository<Message>>();
kernel.Bind<IRepository<User>>().To<GenericRepository<User>>();
NinjectContainer.Initialize(kernel);
My IUnitOfWork
public interface IUnitOfWork
{
IUserService UserService { get; }
ICustomerService CustomerService { get; }
IMessageService MessageService { get; }
void CommitChanges();
}
My UnitOfWork
public class UnitOfWork : IUnitOfWork
{
MyContext _context;
private readonly IUserService _userService;
private readonly ICustomerService _customerService;
private IMessageService _messageService;
public UnitOfWork(IUserService userService,
ICustomerService customerService,
IMessageService messageService,
MyContext context)
{
_userService = userService;
_customerService = customerService;
_messageService = messageService;
SetContext(optimaContext);
}
private void SetContext(MyContext context)
{
_context = context;
_userService.Context = _context;
_customerService.Context = _context;
_messageService.Context = _context;
}
public void CommitChanges()
{
_context.SaveChanges();
}
public IUserService UserService { get { return _userService; } }
public ICustomerService CustomerService { get { return _customerService; } }
public IMessageService MessageService { get { return _messageService; } }
}
My ICustomerService
public interface ICustomerService
{
DbContext Context { get; set; }
IQueryable<Customer> All();
}
My CustomerService
public class CustomerService : ICustomerService
{
IRepository<Customer> _customerRepo;
public CustomerService(IRepository<Customer> customerRepo)
{
_customerRepo = customerRepo;
}
private DbContext _context;
public DbContext Context
{
get { return _context; }
set { _context = value; _customerRepo.Context = value; }
}
public IQueryable<Customer> All()
{
return _customerRepo.All();
}
}
我的其他服务遵循类似的模式。
我的 IRepository
public interface IRepository<T> where T : class, new()
{
DbContext Context { get; set; }
T Single(Expression<Func<T, bool>> expression);
T Find(object id);
IQueryable<T> All();
void Delete(Expression<Func<T, bool>> expression);
void Delete(T item);
}
我的存储库
public class GenericRepository<T> : IRepository<T> where T : class, new()
{
DbContext _context;
public DbContext Context
{
get { return _context; }
set { _context = value; }
}
public virtual T Single(Expression<Func<T, bool>> expression)
{
return All().FirstOrDefault(expression);
}
public virtual T Find(object id)
{
return _context.Set<T>().Find(id);
}
public virtual IQueryable<T> All()
{
return _context.Set<T>();
}
public virtual void Delete(Expression<Func<T, bool>> expression)
{
var items = All().Where(expression);
foreach (var item in items)
{
Delete(item);
}
}
public virtual void Delete(T item)
{
_context.Set<T>().Remove(item);
}
}
如果有人可以帮助 Ninject 映射和注入类的正确方法,我们将不胜感激。
My question is very similar to this one: MVC3 tool using Entity Framework caching issues with Ninject however my mapping is a bit more complex and when I use InRequestScope
I get the following error:
The operation cannot be completed because the DbContext has been disposed.
If I don't include InRequestScope
everything works except EF Code First seems to cache my entities and it doesn't match up to the values in the Db.
Here's my ninject mapping I'm using the ninject mvc3 nuget package (without InRequestScope
):
kernel.Bind<MyContext>()
.ToSelf()
.WithConstructorArgument("connectionString", context => MvcApplication.GetConnectionStringName);
kernel.Bind<IUnitOfWork>().To<UnitOfWork>();
// Service Layer.
kernel.Bind<ICustomerService>().To<CustomerService>();
kernel.Bind<IMessageService>().To<MessageService>();
kernel.Bind<IUserService>().To<UserService>();
// Repository Layer.
kernel.Bind<IRepository<Customer>>().To<GenericRepository<Customer>>();
kernel.Bind<IRepository<Message>>().To<GenericRepository<Message>>();
kernel.Bind<IRepository<User>>().To<GenericRepository<User>>();
NinjectContainer.Initialize(kernel);
My IUnitOfWork
public interface IUnitOfWork
{
IUserService UserService { get; }
ICustomerService CustomerService { get; }
IMessageService MessageService { get; }
void CommitChanges();
}
My UnitOfWork
public class UnitOfWork : IUnitOfWork
{
MyContext _context;
private readonly IUserService _userService;
private readonly ICustomerService _customerService;
private IMessageService _messageService;
public UnitOfWork(IUserService userService,
ICustomerService customerService,
IMessageService messageService,
MyContext context)
{
_userService = userService;
_customerService = customerService;
_messageService = messageService;
SetContext(optimaContext);
}
private void SetContext(MyContext context)
{
_context = context;
_userService.Context = _context;
_customerService.Context = _context;
_messageService.Context = _context;
}
public void CommitChanges()
{
_context.SaveChanges();
}
public IUserService UserService { get { return _userService; } }
public ICustomerService CustomerService { get { return _customerService; } }
public IMessageService MessageService { get { return _messageService; } }
}
My ICustomerService
public interface ICustomerService
{
DbContext Context { get; set; }
IQueryable<Customer> All();
}
My CustomerService
public class CustomerService : ICustomerService
{
IRepository<Customer> _customerRepo;
public CustomerService(IRepository<Customer> customerRepo)
{
_customerRepo = customerRepo;
}
private DbContext _context;
public DbContext Context
{
get { return _context; }
set { _context = value; _customerRepo.Context = value; }
}
public IQueryable<Customer> All()
{
return _customerRepo.All();
}
}
My other services follow a similar patter.
My IRepository
public interface IRepository<T> where T : class, new()
{
DbContext Context { get; set; }
T Single(Expression<Func<T, bool>> expression);
T Find(object id);
IQueryable<T> All();
void Delete(Expression<Func<T, bool>> expression);
void Delete(T item);
}
My Repository
public class GenericRepository<T> : IRepository<T> where T : class, new()
{
DbContext _context;
public DbContext Context
{
get { return _context; }
set { _context = value; }
}
public virtual T Single(Expression<Func<T, bool>> expression)
{
return All().FirstOrDefault(expression);
}
public virtual T Find(object id)
{
return _context.Set<T>().Find(id);
}
public virtual IQueryable<T> All()
{
return _context.Set<T>();
}
public virtual void Delete(Expression<Func<T, bool>> expression)
{
var items = All().Where(expression);
foreach (var item in items)
{
Delete(item);
}
}
public virtual void Delete(T item)
{
_context.Set<T>().Remove(item);
}
}
If anyone can help with the Ninject mapping and the correct way to inject classes it would be greatly appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我发现了问题,当调用该属性时,我正在将
[Inject]
属性与FilterAttribute
一起使用,这是在我的上下文初始化之前生成的dbContext
错误。我在 ninject github 站点此处 在
FilterAttribute
上设置 ninject。我确实遇到的问题是找到BindFilter
方法,该方法隐藏在Ninject.Web.Mvc.FilterBindingSyntax
命名空间中。我的 ninject 映射现在看起来像:
I found the problem, I was using the
[Inject]
attribute with aFilterAttribute
when the attribute was being called it was before my context had been initialised and that producted thedbContext
error.I followed the wiki on the ninject github site here to setup ninject on
FilterAttribute
. On issue I did have was finding theBindFilter
method, this is hidden awayNinject.Web.Mvc.FilterBindingSyntax
namespace.My ninject mappings now look like: