Мой вопрос очень похож на этот: Инструмент MVC3, использующий проблемы кэширования Entity Framework с Ninject , однако мое отображение немного сложнее, и когда я использую InRequestScope
, я получаю следующую ошибку:
Операция не может быть завершена, поскольку был удален DbContext.
Если я не включу InRequestScope
, все работает, кроме EF Code First, похоже, что кеширует мои сущности и этоне совпадает со значениями в БД.
Вот мое сопоставление nject, я использую пакет nuget ninject mvc3 (без 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();
}
Мой 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; } }
}
Мой ICustomerService
public interface ICustomerService
{
DbContext Context { get; set; }
IQueryable<Customer> All();
}
Мой 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 и правильным способом введения классов, это будет очень признательно.