4

我是 MVC3 的新手,一直在关注 asp.net 网站上的精彩教程。但是,我不能完全理解如何将工作单元和通用存储库模式与 Ninject 一起使用。我以本教程为起点:http ://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-the-repository-and-unit-of-work-patterns -in-an-asp-net-mvc-应用程序

不使用接口,我知道我可以像这样实现它:

通用存储库:

public class GenericRepository<TEntity> : IGenericRepository<TEntity>
                                          where TEntity : class
{
    internal MyContext context;
    internal DbSet<TEntity> dbSet;

    public GenericRepository(MyContext context)
    {
        this.context = context;
        this.dbSet = context.Set<TEntity>();
    }
}

工作单位:

private MyContext context = new MyContext();
private GenericRepository<Student> studentRepository;
private GenericRepository<Course> courseRepository;

public GenericRepository<Student> StudentRepository
{
    if (this.studentRepository == null)
    {
        this.studentRepository = new GenericRepository<Student>(context);
    }
    return studentRepository;
}

public GenericRepository<Course> CourseRepository
{
    if (this.courseRepository == null)
    {
        this.courseRepository = new GenericRepository<Course>(context);
    }
    return courseRepository;
}

此设置允许我将相同的上下文传递给所有存储库,然后调用单个 Save() 函数来提交更改。

我知道我可以使用接口IGenericRepository<TEntity>和具体实现GenericRepository<TEntity>,然后使用 Ninject 绑定它们:

kernel.Bind(typeof(IGenericRepository<>)).To(typeof(GenericRepository<>));

但是我将如何设置我的IUnitOfWorkUnitOfWork确保我的所有存储库共享一个数据库上下文?我一开始就做对了吗?我四处搜索,但似乎只找到了只使用通用存储库而没有工作单元的教程。

4

1 回答 1

0

您的基础回购:

public class BaseRepository<TObject> : IRepository<TObject>
     where TObject : class
{

    public BaseRepository(IUnitOfWork unitOfWork)
    {
        if (unitOfWork == null) throw new ArgumentException("unitOfWork");
        UnitOfWork = unitOfWork;
    }

    protected DbSet<TObject> DbSet
    {
        get
        {
            return Context.Set<TObject>();
        }
    }

    public void Dispose()
    {
        if (sharedContext && (Context != null))
            Context.Dispose();
    }

    public virtual IQueryable<TObject> All()
    {
        return DbSet.AsQueryable();
    }

    public virtual IQueryable<TObject>
            Filter(Expression<Func<TObject, bool>> predicate)
    {
        return DbSet.Where(predicate).AsQueryable<TObject>();
    }

    public virtual IQueryable<TObject> Filter<Key>(Expression<Func<TObject, Key>> sortingSelector, Expression<Func<TObject, bool>> filter, out int total,
        SortingOrders sortby = SortingOrders.Asc, int index = 0, int size = 50)
    {
        int skipCount = index * size;
        var _resultSet = filter != null ? DbSet.Where(filter).AsQueryable() : DbSet.AsQueryable();
        total = _resultSet.Count();

        _resultSet = sortby == SortingOrders.Asc ? _resultSet.OrderBy(sortingSelector).AsQueryable() : _resultSet.OrderByDescending(sortingSelector).AsQueryable();
        _resultSet = skipCount == 0 ? _resultSet.Take(size) : _resultSet.Skip(skipCount).Take(size);
        return _resultSet;
    }

    public bool Contains(Expression<Func<TObject, bool>> predicate)
    {
        return DbSet.Count(predicate) > 0;
    }

    public virtual TObject Find(params object[] keys)
    {
        return DbSet.Find(keys);
    }

    public virtual TObject Find(Expression<Func<TObject, bool>> predicate)
    {
        return DbSet.FirstOrDefault(predicate);
    }

    public virtual TObject Create(TObject TObject, bool SaveChanges = true)
    {
        var newEntry = DbSet.Add(TObject);
        if (!sharedContext && SaveChanges)
            Context.SaveChanges();
        return newEntry;
    }

    public virtual int Count
    {
        get
        {
            return DbSet.Count();
        }
    }

    public virtual int Delete(TObject TObject)
    {
        DbSet.Remove(TObject);
        if (!sharedContext)
            return Context.SaveChanges();
        return 0;
    }

    public virtual int Update(TObject TObject, bool SaveChanges = true)
    {
        var entry = Context.Entry(TObject);
        DbSet.Attach(TObject);
        entry.State = EntityState.Modified;
        if (!sharedContext && SaveChanges)
            return Context.SaveChanges();
        return 0;
    }

    public virtual int Delete(Expression<Func<TObject, bool>> predicate)
    {
        var objects = Filter(predicate);
        foreach (var obj in objects)
            DbSet.Remove(obj);
        if (!sharedContext)
            return Context.SaveChanges();
        return 0;
    }

    /// <summary>
    /// Sets the state of an entity.
    /// </summary>
    /// <param name="entity">object to set state.</param>
    /// <param name="entityState"><see cref="EntityState"/></param>
    protected virtual void SetEntityState(object entity, EntityState entityState)
    {
        Context.Entry(entity).State = entityState;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="entity"></param>
    protected virtual void Attach(object entity)
    {
        if (Context.Entry(entity).State == EntityState.Detached)
            Context.Entry(entity).State = EntityState.Modified;
    }


    protected virtual void Detach(object entity)
    {
        Context.Entry(entity).State = EntityState.Detached;
    }

    public void SubmitChanges()
    {
        UnitOfWork.SaveChanges();
    }


    #region Properties

    private bool sharedContext { get; set; }

    /// <summary>
    /// Unit of work controlling this repository.       
    /// </summary>
    protected IUnitOfWork UnitOfWork { get; set; }

    /// <summary>
    /// Provides access to the ef context we are working with
    /// </summary>
    internal IMyContext Context
    {
        get
        {
            return (IMyContext)UnitOfWork;
        }
    }

    #endregion
}

注意 Context 是一个实现 UnitOfWork 的接口。

您的上下文界面:

public interface IMyContext : IDbContext
{
    DbSet<Sometype> SomeProperty { get; set; }
    ...

}

您的 IDbContext 接口:

 public interface IDbContext
{
    DbChangeTracker ChangeTracker { get; }
    DbContextConfiguration Configuration { get; }
    Database Database { get; }

    void Dispose();
    void Dispose(bool disposing);
    DbEntityEntry Entry(object entity);
    DbEntityEntry<TEntity> Entry<TEntity>(TEntity entity) where TEntity : class;
    bool Equals(object obj);
    int GetHashCode();
    Type GetType();
    IEnumerable<DbEntityValidationResult> GetValidationErrors();
    void OnModelCreating(DbModelBuilder modelBuilder);
    int SaveChanges();
    DbSet<TEntity> Set<TEntity>() where TEntity : class;
    DbSet Set(Type entityType);
    bool ShouldValidateEntity(DbEntityEntry entityEntry);
    string ToString();
    DbEntityValidationResult ValidateEntity(DbEntityEntry entityEntry, IDictionary<object, object> items);
}

然后是实际的上下文实现:

 public class MyContext : DbContext, IUnitOfWork, IMyContext
{
    //public MyContext()
    //{
    //    Database.SetInitializer<ReconContext>(null);
    //}

    public ReconContext()
        : base("Name=ReconContext")
    {
        ((IObjectContextAdapter)this).ObjectContext.ContextOptions.ProxyCreationEnabled = false;
    }

    public DbSet<SomeType> SomeProperty { get; set; }
    ....



    public new void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new SomePropertyMap());
        .....
        base.OnModelCreating(modelBuilder);
    }

    int IUnitOfWork.SaveChanges()
    {
        return base.SaveChanges();
    }

    void IDisposable.Dispose()
    {
        base.Dispose();
    }

    public new void Dispose(bool disposing)
    {
        base.Dispose(disposing);
    }

    public new bool ShouldValidateEntity(DbEntityEntry entityEntry)
    {
        return base.ShouldValidateEntity(entityEntry);
    }

    public new DbEntityValidationResult ValidateEntity(DbEntityEntry entityEntry, IDictionary<object, object> items)
    {
        return base.ValidateEntity(entityEntry, items);
    }



}

然后在您的 ninject 配置中,您只需执行以下操作:

kernel.Bind<IUnitOfWork<MyContext>>().To<MyContext>().InRequestScope();
于 2013-09-13T14:32:49.357 回答