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仓库,对于个人来使用已经足够了。

LCLFramework框架之Repository模式设计代码


 

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扩展


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

LCLFramework框架之Repository模式的更多相关文章

  1. LCLFramework框架之Service模式

    Service模式介绍 领域中的一些概念不太适合建模为对象,即归类到实体对象或值对象,因为它们本质上就是一些操作,一些动作,而不是事物.这些操作或动作往往会涉及到多个领域对象,并且需要协调这些领域对象 ...

  2. LCLFramework框架之Plugin模式

    插件应用架构概述 基于LCLFramework插件框架的应用由以下三个部分构成: (1)主程序:针对特定应用环境(Web.WinForm等应用环境),加载启动插件,获取插件入口,运行入口程序. (2) ...

  3. LCLFramework框架 1.1 Pre-Alpha 源码公布

    使用开发框架的好处:1.框架在技术上为软件系统提供了完整的模式实践2.框架为团队提供了合理可行的软件开发过程模式3.框架的应用大大提高了团队的开发效率,团队只需要关注与领域相关的业务实现,而无需关注具 ...

  4. (转)MVC中的Repository模式

    1.首先创建一个空的MVC3应用程序,命名为MyRepository.Web,解决方案命名为MyRepository. 2.添加一个类库项目,命名为MyRepository.DAL,添加一个文件夹命名 ...

  5. Laravel Repository 模式

    Repository 模式 为了保持代码的整洁性和可读性,使用Repository Pattern 是非常有用的.事实上,我们也不必仅仅为了使用这个特别的设计模式去使用Laravel,然而在下面的场景 ...

  6. MVC中的Repository模式

    1.首先创建一个空的MVC3应用程序,命名为MyRepository.Web,解决方案命名为MyRepository. 2.添加一个类库项目,命名为MyRepository.DAL,添加一个文件夹命名 ...

  7. MVC Repository模式

    近来发现很多ASP.NET MVC的例子中都使用了Repository模式,比如Oxite,ScottGu最近发布的免费的ASP.NET MVC教程都使用了该模式.就简单看了下. 在<企业架构模 ...

  8. 在 Laravel 5 中使用 Repository 模式实现业务逻辑和数据访问的分离

    1.概述 首先需要声明的是设计模式和使用的框架以及语言是无关的,关键是要理解设计模式背后的原则,这样才能不管你用的是什么技术,都能够在实践中实现相应的设计模式. 按照最初提出者的介绍,Reposito ...

  9. Repository模式(转载)

    近来发现很多ASP.NET MVC的例子中都使用了Repository模式,比如Oxite,ScottGu最近发布的免费的ASP.NET MVC教程都使用了该模式.就简单看了下. 在<企业架构模 ...

随机推荐

  1. C++ set使用

    C++ set使用 实际上c++ STL中的set是的实现和C++ STL中的map的实现的底层数据结构是一样的,如果我们不在考虑红黑树中的卫星数据,而只是关键字,那么同样不允许key值得重复,那么就 ...

  2. 占位符(placeholder text)

    占位符(placeholder text)是用户在input(输入)框输入任何东西之前放置在input(输入)框中的预定义文本. 你可以用如下方式创建占位符: <input type=" ...

  3. 5.1 Intent

    Intent是不同组件之间相互通讯的纽带,封装了不同组件之间通讯的条件.Intent用于启动Activity, Service, 以及BroadcastReceiver三种组件, 同时还是组件之间通信 ...

  4. spring-data-elasticsearch整合elasticsearch

    花了一个晚上 整合最新版本的spring-data-elasticsearch与elasticsearch,遇到各种版本冲突 之类的问题,测试效果如图: facet搜索:

  5. 【Leetcode】【Hard】Merge Intervals

    Given a collection of intervals, merge all overlapping intervals. For example,Given [1,3],[2,6],[8,1 ...

  6. [51单片机] SPI nRF24L01 无线简单程序 1

    main.c #include <reg51.h> #include <api.h> #define uchar unsigned char /**************** ...

  7. 云端持续集成——AppVeyor拥抱GitHub

    想着你正在做一个网站 终于大功告成了,提交了代码后,你按下了开发环境的Build菜单,一杯咖啡后,Build Succeed,然后连接服务器,开始部署 当你乐滋滋的享受着你的开发成果时,突然发现了一个 ...

  8. 股市T+0技巧

    虽然现在股票不能t+0交易了,不过通过股票t+0技巧可以变相的实现t+0交易,尤其在主力方面应用股票t+0技巧更为明显.主力资金一旦介入某股,肯定会建立很大的仓位作为主仓,然后长线持有.然而为了推动股 ...

  9. HTML5 ——本地存储

    目录 一.HTML4客户端存储 1.1.提交表单发送到服务器的信息 1.2.客户端本地存储概要 二.localStorage 2.1.添加 2.2.取值 2.3.修改 2.4.删除 2.5.跨页面与跨 ...

  10. Origin的图片导出问题

    很多会议投稿都会要求提交的pdf文件用的是type1字体,因为type1字体是矢量字体,无论怎么放大缩小都不会失真.一旦pdf里嵌入了其他非矢量字体,例如type3字体,就会通不过测试,一个典型的例子 ...