c# - 在多层应用程序的 DbContext 上使用 Ninject

标签 c# entity-framework ninject dbcontext n-tier-architecture

我正在尝试掌握 Ninject,但似乎找不到任何可以帮助解决我的问题的文章。我创建了一个简单的 n 层解决方案,其中包含 Web、业务逻辑和数据访问层。在 DAL 中,我为我的数据库(简单的两个表 DB)和通用存储库(IRepositoryItemRepository)创建了一个模型,如下所示。

public interface IRepository<T> where T : class
{
    IQueryable<T> GetAll();
} 

该接口(interface)的实现如下所示。

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>();
    }

}

项目对象

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();
    }

我遇到的问题是,当我使用 Web 项目中的此代码时,我收到“DbContext 已释放”运行时错误。我试图让事情变得简单,只是为了掌握框架,但不明白如何正确获取 DbContext 范围。我已经看过这里的其他文章,但它们都是针对某些场景的,我想掌握正确的基础知识。

有人可以帮助我或为我指明正确的方向吗?

最佳答案

您收到“DbContext 已处置”,因为您在 ItemRepository 上离开 GetAll 方法之前处置它,并且查询为尚未执行。当调用 ToList() 时,查询会在 GetItems 方法内执行 - 此时您的数据上下文已经因为 using 而被释放关闭。如果您想将 Items 作为 IQueryable 返回,则必须让数据上下文保持事件状态,直到完成查询。

我建议将您的 GenericsEntities 绑定(bind)到 Web 应用程序的请求范围(ninject 将在请求时为您处理它)或某些自定义范围(如果它是桌面应用程序)并注入(inject)到您的存储库。

注册

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>();
    }   
}

关于c# - 在多层应用程序的 DbContext 上使用 Ninject,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14160534/

相关文章:

c# - 在 C# 中,如何使用 Console.WriteLine 方法从 SqlCommand 写入所有列

c# - foreach 在匿名类型上

c# - 如何判断光驱(不是光盘)是 CD 驱动器还是 DVD 驱动器?

entity-framework - 有没有简单的方法来生成 Entity Framework 代码优先类?

sql - EF5 使用名称中的点生成 SQL Server CE 约束

c# - 使用 MVC 和 Ninject 作为 IoC 容器构建 WinForms 应用程序

c# - EF Core 通过空检查破坏了构造函数的目的

javascript - 序列化、反序列化 C#/JSON 对象并且没有大小写问题

c# - MVC5 和 Ninject :Parameterless constructor error

asp.net-mvc - ASP.NET MVC 5 过滤器和注入(inject)