Ninject和DbContext

时间:2015-08-26 13:14:38

标签: c# entity-framework ninject inversion-of-control

使用EF 6和Ninject 3.2.2构建应用程序我在如何以智能方式访问DbContext时遇到了一些麻烦。

据我所知,在较新版本的Ninject中,只鼓励构造函数注入。作为EF 6,它本身就是回购和工作单元,我没有在EF上做任何抽象。 如果希望能够使用多个小单元的作品,那么将DbContext(uow)注入到需要它的每个类中是行不通的。 以非IoC的方式,我会这样做:

Using(var db = new DbContext){}

如何使用Ninject实现这一点,因为我无法在我的使用块中执行kernel.get ...

2 个答案:

答案 0 :(得分:1)

我考虑两种方法:

  1. 创建一般DbContext,它可以隐藏在界面后面:

    public interface IPortalContext : IDisposable
    {
        DbSet<User> Users { get; }
    
        DbContext Context { get; }
    }
    
    public class PortalContext : DbContext, IPortalContext
    {
        public PortalContext()
            : base("PortalConnectionString")
        {
        }
    
        public virtual DbSet<User> Users { get; set; }
    }
    

    然后你可以毫无问题地将你的上下文注入构造函数。

  2. 创建许多可在不同场景和类中使用的小上下文。

  3. 我不认为第一种方法很糟糕,因为它只封装了您的DbSetsDbContext,因此更容易注入和测试。你不会在EF之上制作任何不必要的图层,整个界面看起来都很透明。

    无论如何,这种方法比使整个IRepository<T>内容访问另一个存储库更好......

答案 1 :(得分:1)

我不确定“多个小单位作品”是什么意思,但仅仅是为了曝光,这就是我在最近的一个应用程序中所做的:

  1. 在小范围的上下文中划分域名(这更像是一个概念性步骤)
  2. 每个有界上下文都有:上下文,存储库,存储库工厂
  3. 每个上下文实现一个IContext和一个BaseContext,它提供基本方法和公共属性(IContext对模拟很有用)
  4. 每个存储库都将相对上下文作为构造函数参数
  5. 这是存储库工厂的示例

    public class CartRepositoryFactory:IRepositoryFactory     {         public IRepository Generate(CartContext ctx)         {             返回新的CartRepository(ctx);         }     }

  6. 在应用程序服务层,我注入了一个UoW和我需要的存储库工厂

  7. 如果我想在一个服务中使用多个不同的上下文,我只需创建另一个服务并组合我需要的服务,注入它们
  8. 你可能会问,但为什么?!?这很疯狂!!

    好吧,因为如果Repository管理DbContext,那么我每个类实例化只能做一个操作。这允许我打开DbContext并对存储库进行多次调用。 当然,现在您在应用程序服务级别遇到同样的问题,每次实例化只能调用一个方法,但管理起来要容易得多。

    归根结底,这一切都取决于您的口味:您宁愿拥有瘦服务还是薄存储库?