简体   繁体   English

IoC,带有Ninject和实体框架的UnitOfWork

[英]IoC, UnitOfWork with Ninject and Entity Framework

Im trying to implement a generic repository to my service classes. 我正在尝试为我的服务类实现通用存储库。 But when i try to bind my DbConext in Web layer, i need to reference Entity Framework. 但是,当我尝试在Web层中绑定我的DbConext时,我需要引用实体框架。

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

My IUnitOfWork 我的IUnitOfWork

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

My Repository 我的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;
    }
}

And last my Ninject config 最后是我的Ninject配置

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

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

The problem is that Ninject wants the references to Entity Framework, but i dont want to add it here, it belongs to the data layer. 问题是Ninject想要引用实体框架,但是我不想在这里添加它,它属于数据层。

And do you think the ToConstant implementation for DbContext will cause problem? 并且您认为DbContext的ToConstant实现会引起问题吗?

If you do not want to reference the EntityFramework from the top level (eg web) project, how would you build your application? 如果您不想从顶级(例如Web)项目中引用EntityFramework,您将如何构建应用程序? The top level project needs to have references to all underlying dependencies, so they could be put inside bin folder, in the case of web app . 顶级项目需要具有对所有基础依赖项的引用, 因此对于Web应用程序,可以将它们放在bin文件夹中

And definitely it is not Ninject, who wants that reference. 绝对不是Ninject,而是想要该参考。 It is because you are using classes, that depends on EntityFramework in that project. 这是因为您使用的类取决于该项目中的EntityFramework。

There is no problem to have references from the top layer (through middle) to the bottom layer. 从顶层(通过中间)到底层都有引用是没有问题的。 It could be (design) problem, if it would be other way round (eg to have reference from data layer to System.Web ). 如果是其他方式(例如,从数据层到System.Web引用),则可能是(设计)问题。

UPDATE UPDATE

As OP stated in his comment. 正如OP在他的评论中所述。 There is one possible solution to avoid referencing dependencies of the bottom layer (like EF) from the top layer using the ninject.extensions.xml . 有一种可能的解决方案,可以避免使用ninject.extensions.xml从顶层引用底层(如EF)的依赖性 It will work only if the intention was to make ninject configuration in the top layer project, but the project itself is not referencing (using) any of the bottom layer classes with dependencies. 仅当打算在顶层项目中进行ninject配置,而项目本身未引用(使用)任何具有依赖关系的底层类时,此方法才起作用。 Also the EF have to be in GAC. EF也必须位于GAC中。


It is not a good conception to bind your DbContext ToConstant() as long as it implements IDisposable . 这是不绑定您的一个好概念DbContext ToConstant()只要它实现IDisposable DbContext should be bound in the shortest possible Scope meaningful for the application (eg InRequestScope() for web app). 应该将DbContext绑定在对应用程序有意义的最短Scope (例如,Web应用程序的InRequestScope() )。 Ninject will dispose it at the end of the Scope . Ninject会将其放置在Scope的末尾。

If you let DbContext bound ToConstant , it will hold one connection to database per whole application lifecycle. 如果让DbContext绑定到ToConstant ,则它将在整个应用程序生命周期中保持与数据库的一个连接。 You can get into trouble with concurrency issues and the DbContext could become inconsistent, when accessed by multiple threads, because it wont be able to keep up on object synchronization. 您可能会遇到并发问题,并且当被多个线程访问时, DbContext可能会变得不一致,因为它无法跟上对象同步。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM