Использование Ninject в DbContext многоуровневого приложения
Я пытаюсь разобраться с Ninject и не могу найти здесь никаких статей, которые помогли бы решить мою проблему. Я создал простое n-уровневое решение, которое содержит веб, бизнес-логику и уровни доступа к данным. В DAL я создал модель для моей базы данных (простая двухтабличная БД) и универсальных репозиториев (IRepository
и ItemRepository
), которые выглядят следующим образом.
public interface IRepository<T> where T : class
{
IQueryable<T> GetAll();
}
Реализация этого интерфейса выглядит следующим образом.
public class ItemRepository : IRepository<Item>
{
public IQueryable<Item> GetAll()
{
IQueryable<Item> result;
using (GenericsEntities DB = new GenericsEntities()) {
result = DB.Set<Item>();
}
return result;
}
}
В моем BLL я создал DataModule
, Item
Объект и класс (DoWork
) для их использования. Они выглядят следующим образом...
public class DataModule : NinjectModule
{
public override void Load()
{
Bind(typeof(IRepository<>)).To<ItemRepository>();
}
}
Объект Item
public class Item
{
DAL.IRepository<DAL.Item> _repository;
[Inject]
public Item(DAL.IRepository<DAL.Item> repository) {
_repository = repository;
}
public List<DAL.Item> GetItems(){
List<DAL.Item> result = new List<DAL.Item>();
result = _repository.GetAll().ToList();
return result;
}
}
Класс DoWork
public DoWork()
{
var DataKernel = new StandardKernel(new DataModule());
var ItemRepository = DataKernel.Get<IRepository<DAL.Item>>();
Item thisItem = new Item(ItemRepository);
List<DAL.Item> myList = thisItem.GetItems();
}
Проблема заключается в том, что при использовании этого кода из веб-проекта я получаю ошибку времени выполнения "DbContext is disposed". Я пытался сохранить вещи простыми, чтобы просто разобраться с фреймворком, но не понимаю, как правильно получить область DbContext
. Я посмотрел на другие статьи здесь, но все они специфичны для определенных сценариев и я хочу, чтобы основы были правильными.
1 ответ:
Вы получаете "DbContext удален", потому что вы удаляете его перед тем, как оставить Метод
GetAll
на вашемItemRepository
, и запрос еще не выполнен. Запрос выполняется внутри методаGetItems
при вызове методаToList()
- в это время контекст данных уже удален из-за этого закрытияusing
. Если вы хотите вернутьItems
КакIQueryable
, вам придется оставить контекст данных в живых, пока вы не закончите с запросом.Я бы предложил связать ваш
GenericsEntities
в область запроса (ninject разместит ее для вас в и запроса) для веб-приложения или в какой-то пользовательской области, если это настольное приложение и внедрить в ваш репозиторий.Регистрация
Bind<GenericEntities>().ToSelf().InRequestScope();
Репозиторий
public class ItemRepository : IRepository<Item> { private readonly GenericEntities DB; public ItemRepository(GenericEntities db) { this.DB = db; } public IQueryable<Item> GetAll() { return DB.Set<Item>(); } }