luomingui / lclframework Goto Github PK
View Code? Open in Web Editor NEWLCLFramework就是一套在.NET下支持面向领域驱动的软件系统管理类软件的快速开发框架 文档地址:
Home Page: https://luomingui.github.io/LCLFramework
License: Apache License 2.0
LCLFramework就是一套在.NET下支持面向领域驱动的软件系统管理类软件的快速开发框架 文档地址:
Home Page: https://luomingui.github.io/LCLFramework
License: Apache License 2.0
Respository模式在示例中的实际目的小结一下
Repository模式是架构模式,在设计架构时,才有参考价值;
Repository模式主要是封装数据查询和存储逻辑;
Repository模式实际用途:更换、升级ORM 引擎,不影响业务逻辑;
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 where TEntity : class, IEntity
{
IRepositoryContext Context { get; }
void Create(TEntity entity);
void Delete(TEntity entity);
void Update(TEntity entity);
IEnumerable Get(Expression<Func<TEntity, bool>> predicate);
IEnumerable GetAll(PagingInfo paging = null);
TEntity GetByKey(params object[] keyValues);
IEnumerable 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类的红色部分是与WCF交互的代码。通过“数据门户”来决定是本地执行还是网络执行。
*/
public abstract partial class Repository : IRepository
where TEntity : class, IEntity
{
///
/// 是否声明本仓库为本地仓库(客户端只在客户端查询,服务端在服务端查询)
/// </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 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 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 : Repository
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 DoGetAll(PagingInfo paging)
{
if (paging != null)
{
paging.TotalCount = efContext.Context.Set().Count();
return efContext.Context.Set().OrderBy(t => t.ID).Skip(paging.PageNumber - 1 * paging.PageSize).Take(paging.PageSize).ToList();
}
else
{
return efContext.Context.Set().ToList();
}
}
protected override IEnumerable DoGet(Expression<Func<TEntity, bool>> predicate)
{
return efContext.Context.Set().Where(predicate).ToList();
}
protected override TEntity DoGetByKey(params object[] keyValues)
{
return efContext.Context.Set().Find(keyValues);
}
protected override IEnumerable DoGetPage(Expression<Func<TEntity, bool>> predicate, PagingInfo paging = null)
{
if (paging != null)
{
paging.TotalCount = efContext.Context.Set().Count();
return efContext.Context.Set().OrderBy(predicate).Skip((paging.PageNumber - 1) * paging.PageSize).Take(paging.PageSize).ToList();
}
else
{
return efContext.Context.Set().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
{
//仓库扩展
List GetTest();
}
[Serializable]
[RepositoryFor(typeof(Village))]
public class VillageRepository : EntityFrameworkRepository, IVillageRepository
{
private readonly IRepositoryContext context;
public VillageRepository(IRepositoryContext context)
: base(context)
{
this.context = context;
}
//仓库扩展方法
public List GetTest()
{
return new List();
}
}
复制代码
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.