IoC,UnitOfWork与Ninject和Entity Framework

时间:2013-02-05 22:51:29

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

我正在尝试为我的服务类实现通用存储库。 但是当我尝试在Web层中绑定我的DbConext时,我需要引用实体框架。

我的DbContext

  public partial class SalesDbContext : DbContext, IUnitOfWork
    {
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        }

        public DbSet<Activity> Activities { get; set; }

        /// <summary>
        /// Allows saving changes via the IUnitOfWork interface.
        /// </summary>
        void IUnitOfWork.Commit()
        {
            base.SaveChanges();
        } 

我的IUnitOfWork

public interface IUnitOfWork
{
    /// <summary>
    /// Saves changes to all objects that have changed within the unit of work.
    /// </summary>
    void Commit();
}

我的Repository

public class Repository
{
    protected IUnitOfWork UnitOfWork { get; set; }

    protected SalesDbContext Context
    {
        get { return (SalesDbContext)this.UnitOfWork; }
    }

    public Repository(IUnitOfWork unitOfWork)
    {
        if (unitOfWork == null) throw new ArgumentNullException("unitOfWork");
        this.UnitOfWork = unitOfWork;
    }

    private DbSet<TEntity> GetDbSet<TEntity>() where TEntity : class
    {
        return this.Context.Set<TEntity>();
    }

    protected IEnumerable<TEntity> GetAll<TEntity>() where TEntity : class
    {
        return this.GetDbSet<TEntity>()
            .AsEnumerable();
    }

    protected virtual void SetEntityState(object entity, EntityState entityState)
    {
        this.Context.Entry(entity).State = entityState;
    }
}

最后我的Ninject配置

private static void RegisterServices(IKernel kernel)
{
    IUnitOfWork unitOfWork = new SalesDbContext();

    kernel.Bind<IUnitOfWork>().ToConstant(unitOfWork);
    kernel.Bind<IMarketService>().To<MarketService>();
} 

问题在于Ninject想要引用Entity Framework,但我不想在这里添加它,它属于数据层。

您是否认为DbContext的ToConstant实现会导致问题?

1 个答案:

答案 0 :(得分:1)

如果您不想从顶级(例如Web)项目引用EntityFramework,您将如何构建应用程序?顶级项目需要引用所有底层依赖项,以便它们可以放在bin文件夹中,对于Web应用程序

肯定不是Ninject,谁想要那个参考。这是因为您正在使用类,这取决于该项目中的EntityFramework。

从顶层(通过中间)到底层的引用没有问题。它可能是(设计)问题,如果它是另一种方式(例如从数据层引用到System.Web)。

更新

正如OP在他的评论中所述。有一种可能的解决方案可以避免使用ninject.extensions.xml从顶层引用底层(如EF)的依赖关系。 仅当意图在顶层项目中进行ninject配置时才会起作用,但项目本身并未引用(使用)任何具有依赖关系的底层类。 EF也必须在GAC中。


只要实施DbContext,绑定ToConstant() IDisposable就不是一个好主意。 DbContext应该以对应用程序有意义的最短Scope绑定(例如,对于Web应用程序InRequestScope())。 Ninject将在Scope的末尾处置它。

如果让DbContext绑定ToConstant,它将在整个应用程序生命周期中保持与数据库的一个连接。您可能会遇到并发问题,并且DbContext在多个线程访问时可能会变得不一致,因为它无法跟上对象同步。