5

我对 EF 和 Ninject 都是新手,如果这没有意义,请原谅我 :)

我有一个带有 Ninject 和 Ninject.Web.Common 引用的 MVC3 应用程序。我正在尝试将 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;}

    ...
}

我的存储库类:

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(),那么它可以正常工作 - 但这会导致实体框架出现问题,因为对象在数据上下文的多个单独实例中被修改。

4

3 回答 3

6

将您的存储库也设置为 InRequestScope。他们应该在每次请求后处理。

同样使用 MVC,您也应该使用构造函数注入将您的存储库注入到您的控制器实例中。

于 2012-06-22T03:47:32.647 回答
5

自然地,在我发布了一些点击后不久,我就能够解决这个问题。

问题在于 ActionFilters 的行为在 MVC3 中发生了更改,并且我有一个过滤器注入了我的 ProductService。

我想过滤器处理了服务,最终处理了 DbContext。

就我而言,解决方案很简单。我创建了第二个 DbContext,专门用于我的过滤器。由于过滤器仅查询几个表以验证对特定资源的授权,因此我不需要 DbContext 在单个请求中提供的工作单元上下文。我创建了一个使用新 DbContext 的新服务。在这种情况下,配置 InTransientScope() 就足够了

于 2012-06-22T03:50:11.117 回答
0

我反对将 DbContext 放在 RequestScope 中,因为根据 NInject 文档,RequestScope 依赖于 HttpContext。不能保证在您的请求结束时处理。

我曾经尝试将 DbContext 放在各种对象范围内,但似乎总是得到不一致的结果。

Ninject 内核维护对作用域对象的弱引用,并且当对作用域对象的弱引用不再有效时,将自动处理与作用域对象关联的对象。由于 InRequestScope() 使用 HttpContext.Current 或 OperationContext.Current 作为作用域对象,因此在销毁 HttpContext.Current 或 OperationContext.Current 之前,创建的任何关联对象都不会被销毁。由于 IIS/ASP.NET 管理这些对象的生命周期,因此对象的处置与 IIS/.NET 决定销毁它们的时间相关联,这可能是不可预测的。

于 2018-10-03T20:49:51.790 回答