【问题标题】:IoC, UnitOfWork with Ninject and Entity FrameworkIoC、UnitOfWork 与 Ninject 和实体框架
【发布时间】:2013-02-05 22:51:28
【问题描述】:

我正在尝试为我的服务类实现一个通用存储库。 但是当我尝试在 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想要实体框架的引用,但是我不想在这里添加,它属于数据层。

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

【问题讨论】:

  • 它想要它是因为 SalesDbContext。如果您在 ninject 配置中使用 System.Data.Entity 中的任何类型,那么您将需要引用 entityframework。

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


【解决方案1】:

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

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

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

更新

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


绑定你的DbContextToConstant()不是一个好的概念,只要它实现了IDisposableDbContext 应绑定在对应用程序有意义的最短 Scope 中(例如,InRequestScope() 用于 Web 应用程序)。 Ninject 将在Scope 的末尾处理它。

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

【讨论】:

  • 确实如此。现在每个请求的上下文。我通过在单独的 xml 配置文件中映射接口和类解决了这个问题,然后我不需要在 web 层中引用实体框架。谢谢!
  • 哇,有趣的解决方案。 请记住,它仅适用于将 EF 存储在 GAC 中的机器(但是,只要 EF 默认在 GAC 中,这不是一个大问题)。如果您不介意,我会更新我的答案。
猜你喜欢
  • 2013-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多