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

时间:2013-01-04 16:04:16

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

我正试图与Ninject交手,似乎无法在这里找到任何有助于解决我的问题的文章。我创建了一个简单的n层解决方案,其中包含Web,业务逻辑和数据访问层。在DAL中,我为我的数据库(简单的两个表DB)和通用存储库(IRepositoryItemRepository)创建了一个模型,如下所示。

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

我遇到的问题是,当我使用Web项目中的代码时,我得到一个“DbContext被丢弃”运行时错误。我试图保持简单只是为了掌握框架,但不明白如何使DbContext范围正确。我已经看过这里的其他文章,但有些特定于某些场景,我希望得到正确的基础知识。

任何人都可以帮助或指出我正确的方向吗?

1 个答案:

答案 0 :(得分:2)

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

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

<强>注册

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