zoukankan      html  css  js  c++  java
  • LCLFramework框架之Repository模式

    Respository模式在示例中的实际目的小结一下


    1. Repository模式是架构模式,在设计架构时,才有参考价值;
    2. Repository模式主要是封装数据查询和存储逻辑;
    3. Repository模式实际用途:更换、升级ORM 引擎,不影响业务逻辑;
    4. Repository模式能提高测试效率,单元测试时,用Mock对象代替实际的数据库存取,可以成倍地提高测试用例运行速度。

    Repository与Dal的区别


         Repository是DDD中的概念,强调Repository是受Domain驱动的,Repository中定义的功能要体现Domain的意图和约束,而Dal更纯粹的就是提  供数据访问的功能,并不严格受限于Business层。

         使用Repository,隐含着一种意图倾向,就是 Domain需要什么我才提供什么,不该提供的功能就不要提供,一切都是以Domain的需求为核心;而使用Dal,其意图倾向在于我Dal层能使用的数 据库访问操作提供给Business层,你Business要用哪个自己选。换一个Business也可以用我这个Dal,一切是以我Dal能提供什么操 作为核心。

    LCLFramework框架之Repository模式设计


         LCLFramework框架之Repository模式设计主要是参考http://apworks.codeplex.com/ 框架而来的,目前我只是扩展了LCL.Repositories.EntityFramework仓库,对于个人来使用已经足够了。

    ard_thumb[1]

    LCLFramework框架之Repository模式设计代码


    clipboard[1] 

    public interface IRepository<TEntity> where TEntity : class, IEntity
      {
          IRepositoryContext Context { get; }
          void Create(TEntity entity);
          void Delete(TEntity entity);
          void Update(TEntity entity);
          IEnumerable<TEntity> Get(Expression<Func<TEntity, bool>> predicate);
          IEnumerable<TEntity> GetAll(PagingInfo paging = null);
          TEntity GetByKey(params object[] keyValues);
          IEnumerable<TEntity> GetPage(Expression<Func<TEntity, bool>> predicate,PagingInfo paging);
      }
    public interface IRepositoryContext : IUnitOfWork, IDisposable
    {
        Guid ID { get; }
        void RegisterNew(object obj);
        void RegisterModified(object obj);
        void RegisterDeleted(object obj);
    } 
    
    public interface IUnitOfWork
    {
        bool DistributedTransactionSupported { get; }
        bool Committed { get; }
        void Commit();
        void Rollback();
    }
    /* 
    
    职责: 
    
       1:定义一个“仓库”基类 
    
       2:与WCF交互,Repository<TEntity>类的红色部分是与WCF交互的代码。通过“数据门户”来决定是本地执行还是网络执行。 
    
    */ 
    
    public abstract partial class Repository<TEntity> : IRepository<TEntity>
        where TEntity : class, IEntity
    {
        /// <summary>
        /// 是否声明本仓库为本地仓库(客户端只在客户端查询,服务端在服务端查询)
        /// </summary>
    public DataPortalLocation DataPortalLocation { get; protected set; } 
    
        private readonly IRepositoryContext context;
        public Repository(IRepositoryContext context)
        {
            this.context = context;
    this.DataPortalLocation = DataPortalLocation.Dynamic;
        }
        public IRepositoryContext Context
        {
            get { return this.context; }
        }
        #region IRepositoryContext
        #region CUD
        protected abstract void DoAdd(TEntity entity);
        protected abstract void DoRemove(TEntity entity);
        protected abstract void DoUpdate(TEntity entity);
        [Obfuscation]
        public void Create(TEntity entity)
        {
       this.FetchList(entity, "DoAdd");
        }
        public void Delete(TEntity entity)
        {
    this.FetchList(entity, "DoRemove");
        }
        public void Update(TEntity entity)
        {
    this.FetchList(entity, "DoUpdate");
        }
        #endregion 
    
        #region Query
        protected abstract IEnumerable<TEntity> DoGetAll(PagingInfo paging);
        protected abstract IEnumerable<TEntity> DoGet(Expression<Func<TEntity, bool>> predicate);
        protected abstract TEntity DoGetByKey(params object[] keyValues);
        protected abstract IEnumerable<TEntity> DoGetPage(Expression<Func<TEntity, bool>> predicate, PagingInfo paging);
        public IEnumerable<TEntity> Get(Expression<Func<TEntity, bool>> predicate)
        {
    var list = this.FetchList(predicate, "DoGet");
            return list;
        }
        public IEnumerable<TEntity> GetAll(PagingInfo paging=null)
        {
      var list = this.FetchList(paging, "DoGetAll");
            return list;
        }
        public TEntity GetByKey(params object[] keyValues)
        {
    var list = this.FetchFirst(keyValues, "GetByKey");
            return list;
        }
        public IEnumerable<TEntity> GetPage(Expression<Func<TEntity, bool>> predicate,PagingInfo paging=null)
        {
    return this.FetchList(paging, "GetPage");
        }
        #endregion
        #endregion 
    
           #region 获取对象接口方法 
    
            protected TEntityList FetchListCast<TEntityList>(object criteria, string methodName) 
    
                where TEntityList : class, IEnumerable<TEntity> 
    
            { 
    
                return this.FetchList(criteria, methodName) as TEntityList; 
    
            } 
    
            protected TEntity FetchFirstAs(object criteria, string methodName) 
    
            { 
    
                return this.FetchFirst(criteria,methodName) as TEntity; 
    
            } 
    
            protected IEnumerable<TEntity> FetchList(object criteria, string methodName) 
            { 
                // 调用 " 数据门户 " 
                var list = DataPortalApi.Action(this.GetType(), methodName, criteria, this.DataPortalLocation) as IEnumerable<TEntity>; 
                return list; 
            } 
    
            protected TEntity FetchFirst(object criteria, string methodName) 
    
            { 
    
                var list = this.FetchList(criteria, methodName); 
    
                var last = list.DefaultIfEmpty<TEntity>() as TEntity; 
    
                return list.Count() > 0 ? last : null; 
    
            } 
    
            #endregion
    } 
    
    public abstract class RepositoryContext :DisposableObject,IRepositoryContext 
    
    { 
    
            #region Private Fields 
    
            private readonly Guid id = Guid.NewGuid(); 
    
            private readonly ThreadLocal<List<object>> localNewCollection = new ThreadLocal<List<object>>(() => new List<object>()); 
    
            private readonly ThreadLocal<List<object>> localModifiedCollection = new ThreadLocal<List<object>>(() => new List<object>()); 
    
            private readonly ThreadLocal<List<object>> localDeletedCollection = new ThreadLocal<List<object>>(() => new List<object>()); 
    
            private readonly ThreadLocal<bool> localCommitted = new ThreadLocal<bool>(() => true); 
    
            #endregion 
    
            #region Protected Properties 
    
            protected IEnumerable<object> NewCollection 
    
            { 
    
                get { return localNewCollection.Value; } 
    
            } 
    
            protected IEnumerable<object> ModifiedCollection 
    
            { 
    
                get { return localModifiedCollection.Value; } 
    
            } 
    
            protected IEnumerable<object> DeletedCollection 
    
            { 
    
                get { return localDeletedCollection.Value; } 
    
            } 
    
            #endregion 
    
            #region Protected Methods 
    
            protected void ClearRegistrations() 
    
            { 
    
                this.localNewCollection.Value.Clear(); 
    
                this.localModifiedCollection.Value.Clear(); 
    
                this.localDeletedCollection.Value.Clear(); 
    
            } 
    
            #endregion 
    
            #region IRepositoryContext Members 
    
            public Guid ID 
    
            { 
    
                get { return id; } 
    
            } 
    
            public virtual void RegisterNew(object obj) 
    
            { 
    
                localNewCollection.Value.Add(obj); 
    
                Committed = false; 
    
            } 
    
            public virtual void RegisterModified(object obj) 
    
            { 
    
                if (localDeletedCollection.Value.Contains(obj)) 
    
                    throw new InvalidOperationException("The object cannot be registered as a modified object since it was marked as deleted."); 
    
                if (!localModifiedCollection.Value.Contains(obj) && !localNewCollection.Value.Contains(obj)) 
    
                    localModifiedCollection.Value.Add(obj); 
    
                Committed = false; 
    
            } 
    
            public virtual void RegisterDeleted(object obj) 
    
            { 
    
                if (localNewCollection.Value.Contains(obj)) 
    
                { 
    
                    if (localNewCollection.Value.Remove(obj)) 
    
                        return; 
    
                } 
    
                bool removedFromModified = localModifiedCollection.Value.Remove(obj); 
    
                bool addedToDeleted = false; 
    
                if (!localDeletedCollection.Value.Contains(obj)) 
    
                { 
    
                    localDeletedCollection.Value.Add(obj); 
    
                    addedToDeleted = true; 
    
                } 
    
                localCommitted.Value = !(removedFromModified || addedToDeleted); 
    
            } 
    
            #endregion 
    
            #region IUnitOfWork Members 
    
            public virtual bool DistributedTransactionSupported 
    
            { 
    
                get { return false; } 
    
            } 
    
            public virtual bool Committed 
    
            { 
    
                get { return localCommitted.Value; } 
    
                protected set { localCommitted.Value = value; } 
    
            } 
    
            public abstract void Commit(); 
    
            public abstract void Rollback(); 
    
            #endregion 
    
            protected override void Dispose(bool disposing) 
    
            { 
    
                if (disposing) 
    
                { 
    
                    this.localCommitted.Dispose(); 
    
                    this.localDeletedCollection.Dispose(); 
    
                    this.localModifiedCollection.Dispose(); 
    
                    this.localNewCollection.Dispose(); 
    
                } 
            } 
    }

     

    LCLFramework框架之Repository扩展


    clipboard[2]

    public class EntityFrameworkRepository<TEntity> : Repository<TEntity> 
            where TEntity : class, IEntity 
        { 
            private readonly IEntityFrameworkRepositoryContext efContext; 
            public EntityFrameworkRepository(IRepositoryContext context) 
                : base(context) 
            { 
                if (context is IEntityFrameworkRepositoryContext) 
                    this.efContext = context as IEntityFrameworkRepositoryContext; 
            } 
            protected override void DoAdd(TEntity entity) 
            { 
                efContext.RegisterNew(entity); 
            } 
            protected override void DoRemove(TEntity entity) 
            { 
                efContext.RegisterDeleted(entity); 
            } 
            protected override void DoUpdate(TEntity entity) 
            { 
                efContext.RegisterModified(entity); 
            } 
            protected override IEnumerable<TEntity> DoGetAll(PagingInfo paging) 
            { 
                if (paging != null) 
                { 
                    paging.TotalCount = efContext.Context.Set<TEntity>().Count(); 
                    return efContext.Context.Set<TEntity>().OrderBy(t => t.ID).Skip(paging.PageNumber - 1 * paging.PageSize).Take(paging.PageSize).ToList(); 
                } 
                else 
                { 
                    return efContext.Context.Set<TEntity>().ToList(); 
                } 
            } 
            protected override IEnumerable<TEntity> DoGet(Expression<Func<TEntity, bool>> predicate) 
            { 
                return efContext.Context.Set<TEntity>().Where(predicate).ToList(); 
            } 
            protected override TEntity DoGetByKey(params object[] keyValues) 
            { 
                return efContext.Context.Set<TEntity>().Find(keyValues); 
            } 
            protected override IEnumerable<TEntity> DoGetPage(Expression<Func<TEntity, bool>> predicate, PagingInfo paging = null) 
            { 
                if (paging != null) 
                { 
                    paging.TotalCount = efContext.Context.Set<TEntity>().Count(); 
                    return efContext.Context.Set<TEntity>().OrderBy(predicate).Skip((paging.PageNumber - 1) * paging.PageSize).Take(paging.PageSize).ToList(); 
                } 
                else 
                { 
                    return efContext.Context.Set<TEntity>().OrderBy(predicate).ToList(); 
                } 
            } 
        } 
    public interface IEntityFrameworkRepositoryContext : IRepositoryContext 
    { 
            DbContext Context { get; } 
    } 
    public class EntityFrameworkRepositoryContext : RepositoryContext, IEntityFrameworkRepositoryContext 
        { 
            #region Private Fields 
            private readonly DbContext efContext; 
            private readonly object sync = new object(); 
            #endregion 
            #region Ctor 
            public EntityFrameworkRepositoryContext(DbContext efContext) 
            { 
                this.efContext = efContext; 
            } 
            #endregion 
            #region Protected Methods 
            protected override void Dispose(bool disposing) 
            { 
                if (disposing) 
                { 
                    efContext.Dispose(); 
                } 
                base.Dispose(disposing); 
            } 
            #endregion 
            #region IEntityFrameworkRepositoryContext Members 
            public DbContext Context 
            { 
                get { return this.efContext; } 
            } 
            #endregion 
            #region IRepositoryContext Members 
            public override void RegisterNew(object obj) 
            { 
                this.efContext.Entry(obj).State = System.Data.Entity.EntityState.Added; 
                Committed = false; 
            } 
            public override void RegisterModified(object obj) 
            { 
                this.efContext.Entry(obj).State = System.Data.Entity.EntityState.Modified; 
                Committed = false; 
            } 
            public override void RegisterDeleted(object obj) 
            { 
                this.efContext.Entry(obj).State = System.Data.Entity.EntityState.Deleted; 
                Committed = false; 
            } 
            #endregion 
            #region IUnitOfWork Members 
            public override bool DistributedTransactionSupported 
            { 
                get { return true; } 
            } 
            public override void Commit() 
            { 
                if (!Committed) 
                { 
                    lock (sync) 
                    { 
                        efContext.SaveChanges(); 
                    } 
                    Committed = true; 
                } 
            } 
            public override void Rollback() 
            { 
                Committed = false; 
            } 
            #endregion 
        }

      LCLFramework框架之Repository使用


    public class Village : DomainEntity 
        { 
            public string Name { get; set; } 
        }   
    public interface IVillageRepository : IRepository<Village> 
        { 
            //仓库扩展 
            List<Village> GetTest(); 
        } 
        [Serializable] 
        [RepositoryFor(typeof(Village))] 
        public class VillageRepository : EntityFrameworkRepository<Village>, IVillageRepository 
        { 
            private readonly IRepositoryContext context; 
            public VillageRepository(IRepositoryContext context) 
                : base(context) 
            { 
               this.context = context; 
            } 
            //仓库扩展方法 
            public List<Village> GetTest() 
            { 
                return new List<Village>(); 
            } 
        }
  • 相关阅读:
    怎么知道银行卡号对应的银行
    集合排序、map、枚举
    669. Trim a Binary Search Tree修剪二叉搜索树
    17. Merge Two Binary Trees 融合二叉树
    226. Invert Binary Tree 翻转二叉树
    530.Minimum Absolute Difference in BST 二叉搜索树中的最小差的绝对值
    191. Number of 1 Bits 二进制中1的个数
    Hamming Distance二进制距离
    136. Single Number唯一的数字
    276. Paint Fence篱笆涂色
  • 原文地址:https://www.cnblogs.com/luomingui/p/4117543.html
Copyright © 2011-2022 走看看