2012-06-22 4 views
5

Я новичок в обоих EF и Ninject так простите меня, если это не имеет смысла :)DbContext Disposed после первого запроса при использовании InRequestScope Ninject в()

У меня есть приложение MVC3 с Ninject и Ninject.Web. Общие ссылки. Я пытаюсь ввести DbContext в свои репозитории. То, что я вижу в том, что по первому требованию, все работает замечательно, но последующие запросы возвращают:

System.InvalidOperationException: The operation cannot be completed because the DbContext has been disposed. 
    at System.Data.Entity.Internal.LazyInternalContext.InitializeContext() 
    at System.Data.Entity.Internal.Linq.DbQueryProvider.Execute[TResult](Expression expression) 
    at System.Linq.Queryable.SingleOrDefault[TSource](IQueryable`1 source, Expression`1 predicate) 

Мои привязок:

kernel.Bind<ISiteDataContext>().To<SiteDataContext>().InRequestScope(); 
kernel.Bind<IProductRepository>().To<ProductRepository>(); 
kernel.Bind<IProductService>().To<ProductService>(); 

Моя_служба класс:

public class ProductService : IProductService { 
    [Inject] 
    public IProductRepository repository {get; set;} 

    ... 
} 

Мой Repository класс:

public class ProductRepository : IProductRepository { 
    [Inject] 
    public ISiteDataContext context {get; set;} 

    ... 
} 

Мой класс SiteDataContext:

public class SiteDataContext : DbContext, ISiteDataContext 
{ 
    static SiteDataContext() 
    { 
     Database.SetInitializer<SiteDataContext >(null); 
    } 

    public DbSet<Product> Products{ get; set; } 


    protected override void Dispose(bool disposing) 
    { 
     base.Dispose(disposing); 
    } 
} 

Мой контроллер:

public class ProductController { 
    [Inject] 
    public IProductService productService {get; set;} 

    ... 
} 

Если удалить .InRequestScope(), то он работает отлично - но тогда возникают проблемы с Entity Framework, так как объекты изменяются в несколько отдельных примеры контекста данных.

ответ

5

Естественно, вскоре после публикации что-то щелкнуло в моем уме, и я смог решить это.

Проблема заключается в том, что поведение ActionFilters было изменено в MVC3, и у меня был фильтр, в который был введен мой ProductService.

Я полагаю, что фильтр удалил сервис и в конечном итоге удалил DbContext.

В моем случае решение было легким. Я создал второй DbContext, который используется специально для моего фильтра. Поскольку фильтр делает не что иное, как запрашивать несколько таблиц для проверки полномочий на определенные ресурсы, мне не нужен контекст Unit of Work, который DbContext предоставляет по одному запросу. Я создал новую службу, которая использует новый DbContext. В этом случае достаточно сконфигурировать с InTransientScope()

6

Установите свои репозитории как InRequestScope. Они должны располагать после каждого запроса.

Также с помощью MVC вы должны использовать инъекцию конструктора для инъекции своего репозитория в экземпляр вашего контроллера.

+0

Есть ли преимущества для инжекции конструктора и впрыска атрибута? –

+1

Абсолютно, он придерживается корня композиции. Использовать атрибуты для этого шаблона не подходит по нескольким причинам. Использование инсталляции конструктора здесь отлично работает, и оно позволяет определить зависимости в кратчайшие сроки, и поскольку нет причин, чтобы это было как необязательная зависимость со значением по умолчанию здесь, это предпочтительный метод. См. Http://www.manning.com/seemann/, который является лучшей книгой имхо по этому вопросу. –

+1

Я использую DependencyResolver.Current.GetService <... вместо инъекции бизнес-структур. Возможно ли, что это вызывает ту же проблему? (Операция не может быть завершена, поскольку DbContext был удален) –

Смежные вопросы