c# - IoC、UnitOfWork 与 Ninject 和 Entity Framework

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

我正在尝试为我的服务类实现一个通用存储库。 但是当我尝试在 Web 层中绑定(bind)我的 DbConext 时,我需要引用 Entity Framework 。

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

我的存储库

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 实现会导致问题吗?

最佳答案

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

绝对不是 Ninject,他想要那个引用。这是因为您正在使用类,这取决于该项目中的 EntityFramework。

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

更新

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


绑定(bind)您的 DbContext ToConstant() 并不是一个好主意,只要它实现了 IDisposableDbContext 应该绑定(bind)在对应用程序有意义的尽可能短的 Scope 中(例如 InRequestScope() 用于网络应用程序)。 Ninject 将在 Scope 的末尾处理它。

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

关于c# - IoC、UnitOfWork 与 Ninject 和 Entity Framework ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14718495/

相关文章:

c# - Entity Framework 使用模型与 sqlce 和 sql server/sql express 数据库

c# - 在 Entity Framework 中使用 linq 提供多个 List<int> 类型标准

c# - StructureMap 对象重新加载

c# - .NET 资源文件只有在与 MVC View 位于同一文件夹中时才能成功引用

c# - 有什么简单的方法可以在 C# 中创建方法并动态设置其主体吗?

c# - EF 5、.Net 4.5 加载多对一子对象时出现问题

asp.net - Entity Framework 第一次加载非常慢

C# + MongoDB - 不使用 MongoDB 数据类型/属性的 ObjectId

c# - 模拟数据访问器

c# - LINQ 等效于 std::partition