一直都想写博客,可惜真的太懒了或者对自己的描述水平不太自信,所以。。。一直都是不想写的状态,关于领域驱动的东西看了不少,但是由于自己水平太差加上工作中实在用不到,所以一直处于搁置状态,最近心血来潮突然想重新写一个自己的项目架构,于是开始了新一论的学习历程。

在设计之前我理了一下自己的大致需求也参考了不同人的项目架构,在此特别感谢郭明峰的OSharp给我的启示,每个人对架构的需求和使用习惯都是不一至的,在不同大小的项目上使用的架构也不尽相同,如何取舍性能、开发速度及维护性的问题上每开发者都在自己心中有一杆秤,下面谈谈我理想中的架构,它应该提供一些常用的操作封装及各种工具方便实现多个功能,他应该包括数据操作的方便处理,他应该提供日志及缓存的处理功能,它的每种实现是自己换的但又得具有默认值让我在做私单的时候更快捷方便,基于以上特点于是总结了如下模块:

1,工具库:提供了各种常用操作,如字符串截取,各种验证之类的helper类

2,核心库:提供缓存日志数据的接口及缓存日志的基础实现

3,WEB库:针对网站相关的扩展及操作封装

4,MVC库:针对MVC网站的相关扩展及操作封装

5,基础数据库模块实现库(如:EF)

回到每个架构的重点:数据访问模块上来,现在比较流行使用EF+ IUnitOfWork+Repository来实现数据的处理,诚然这种方式让每一个模块相互的依赖变得更小,更方便测试,更XXX,但是在我的实践中,还是发现他真的麻烦,在我做一个中小项目的时候,添加一个普通的表不得不去添加实体,实体配置,仓储接口,仓储实现,服务接口,服务实现,controller viewmodel,view一系列下来即便是拷贝也是非常慢,即使我们可以用代码生成器,我还是觉得太麻烦了。当然Repository模式的反对者也不少,作为一种数据操作的隔离手段,我个人觉得Repository还是很有必要存在的,经过各种取舍,最后自己使用了一种折中的方式来使用Repository,我的方式是使用IStore来代替IUnitOfWork,本质是一样的,只是IStore实现的功能要多一些,同时使用了IStore使得我们可以很容易的替换我们的数据库功能实现,如下图:

由于一般的项目不需要一人写定义一人写实现,所以直接省去了IUserRepository及IUserService这种并不会修改实现的接口,当然如果有团队共同开发的时候使用也是完全没有问题的,有了以上的图就开以开始实现代码了:

IDataStore:

 /// <summary>
/// 数据存储器接口
/// </summary>
public interface IStore : IDisposable
{
#region UnitOfWork
/// <summary>
/// 获取或设置 是否开启事务提交
/// </summary>
bool TransactionEnabled { get; set; }
/// <summary>
/// 提交操作
/// </summary>
bool Commit();
/// <summary>
/// 异步提交
/// </summary>
Task<bool> CommitAsync();
#endregion #region 基础操作
/// <summary>
/// 添加对像
/// </summary>
void Add<TEntity>(TEntity entity) where TEntity : class;
/// <summary>
/// 更新对像
/// </summary>
void Update<TEntity>(TEntity entity) where TEntity : class;
/// <summary>
/// 删除对像
/// </summary>
void Remove<TEntity>(TEntity entity) where TEntity : class;
#endregion #region 查询操作
/// <summary>
/// 获取数据集查询对像
/// </summary>
IQueryable<TEntity> GetQueryEntities<TEntity, TKey>() where TEntity : class;
#endregion
}

IRepository:

/// <summary>
/// 仓储接口
/// </summary>
/// <typeparam name="TEntity">实体类型</typeparam>
/// <typeparam name="TKey">实体主键类型</typeparam>
public interface IRepository<TEntity, TKey>
{
#region 属性
/// <summary>
/// 获取当前数据存储器
/// </summary>
IStore DataStore { get; }
/// <summary>
/// 获取当前实体的查询数据集
/// </summary>
IQueryable<TEntity> Entities { get; }
#endregion #region 基础操作
/// <summary>
/// 添加实体到仓库
/// </summary>
void Add(TEntity entity);
/// <summary>
/// 更新仓库中的实体
/// </summary>
void Update(TEntity entity);
/// <summary>
/// 从仓库删除指定key的实体
/// </summary>
void Remove(TEntity entity);
#endregion #region 查询
/// <summary>
/// 获取指定key的实体
/// </summary>
TEntity FindByKey(TKey key);
#endregion
}

RepositroyBase:

 /// <summary>
/// 仓储基类
/// </summary>
public abstract class RepositoryBase<TEntity, TKey> : IRepository<TEntity, TKey>
where TEntity : EntityBase<TKey>, new()
{ public IStore DataStore { get; set; } public IQueryable<TEntity> Entities
{
get { return this.DataStore.GetQueryEntities<TEntity, TKey>(); }
} public void Add(TEntity entity)
{
this.DataStore.Add<TEntity>(entity);
} public void Update(TEntity entity)
{
this.DataStore.Update<TEntity>(entity);
} public void Remove(TEntity entity)
{
this.DataStore.Remove<TEntity>(entity);
} public TEntity FindByKey(TKey key)
{
return this.Entities.Where(t => t.Id.Equals(key)).SingleOrDefault();
}
}

当然BaseEntity这种东西就看自己爱好添加了,按key删除,按条件更新的方法这里就不写了

,另外关于返回Repository返回IEnumerable还是IQueryable这个问题我个人认为如果不按照DDD的的标准来看,一个仓库每次拿你想要的东西还是给你一个通道你想拿多少就拿多少本质上都是可以的,不过对于隔离开发人员直接操作数据确实存在隐患,不过谁叫他简单呢?看完定义,然后如果要使用EF做为ORM来操作数据库或者任意继承至IDataStore的库来完成数据操作,不过这里要自己写的话,解析表达式还是有点困难的。。贴下简单EF基类的简单实现:

 /// <summary>
/// EF数据存储器(抽象类)
/// </summary>
public abstract class EFDataStore : DbContext, IStore
{
#region DbContext
protected EFDataStore() { }
protected EFDataStore(DbCompiledModel model) : base(model) { }
public EFDataStore(string nameOrConnectionString) : base(nameOrConnectionString) { }
public EFDataStore(DbConnection existingConnection, bool contextOwnsConnection) : base(existingConnection, contextOwnsConnection) { }
public EFDataStore(ObjectContext objectContext, bool dbContextOwnsObjectContext) : base(objectContext, dbContextOwnsObjectContext) { }
public EFDataStore(string nameOrConnectionString, DbCompiledModel model) : base(nameOrConnectionString, model) { }
public EFDataStore(DbConnection existingConnection, DbCompiledModel model, bool contextOwnsConnection) : base(existingConnection, model, contextOwnsConnection) { }
/// <summary>
/// 实体映射集合
/// </summary>
public IEnumerable<IEntityMapper> EntityConfigurations { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//foreach (var mapper in EntityConfigurations)
//{
// mapper.RegistTo(modelBuilder.Configurations);
//}
}
#endregion public bool TransactionEnabled { get; set; } public IQueryable<TEntity> GetQueryEntities<TEntity, TKey>() where TEntity : class
{
return this.Set<TEntity>();
} public bool Commit()
{
var r = this.SaveChanges();
//this.Dispose();
return r > ;
} public async Task<bool> CommitAsync()
{
return (await this.SaveChangesAsync()) > ;
} public void Add<TEntity>(TEntity entity) where TEntity : class
{
this.Set<TEntity>().Add(entity);
} public void Update<TEntity>(TEntity entity) where TEntity : class
{
this.Entry(entity).State = EntityState.Modified;
} public void Remove<TEntity>(TEntity entity) where TEntity : class
{
this.Entry(entity).State = EntityState.Deleted;
}
}

这。写着写着自己都有点不知所云了,希望对正在学习阶段的朋友有一点点帮助!

关于MVC EF架构及Repository模式的一点心得的更多相关文章

  1. ASP.Net MVC+EF架构

    ASP.Net MVC是UI层的框架,EF是数据访问的逻辑. 如果在Controller中using DbContext,把查询的结果的对象放到cshtml中显示,那么一旦在cshtml中访问关联属性 ...

  2. 项目开发中的一些注意事项以及技巧总结 基于Repository模式设计项目架构—你可以参考的项目架构设计 Asp.Net Core中使用RSA加密 EF Core中的多对多映射如何实现? asp.net core下的如何给网站做安全设置 获取服务端https证书 Js异常捕获

    项目开发中的一些注意事项以及技巧总结   1.jquery采用ajax向后端请求时,MVC框架并不能返回View的数据,也就是一般我们使用View().PartialView()等,只能返回json以 ...

  3. MVC架构中的Repository模式 个人理解

    关于MVC架构中的Repository模式   个人理解:Repository是一个独立的层,介于领域层与数据映射层(数据访问层)之间.它的存在让领域层感觉不到数据访问层的存在,它提供一个类似集合的接 ...

  4. MVC实用架构设计(三)——EF-Code First(1):Repository,UnitOfWork,DbContext

    前言 终于到EF了,实在不好意思,最近有点忙,本篇离上一篇发布已经一个多星期了,工作中的小迭代告一段落,终于有点时间来继续我们的架构设计了,在这里先对大家表示歉意. 其实这段时间我并不是把这个系列给忘 ...

  5. 基于Repository模式设计项目架构—你可以参考的项目架构设计

    关于Repository模式,直接百度查就可以了,其来源是<企业应用架构模式>.我们新建一个Infrastructure文件夹,这里就是基础设施部分,EF Core的上下文类以及Repos ...

  6. MVC+EF 理解和实现仓储模式和工作单元模式

    MVC+EF 理解和实现仓储模式和工作单元模式 原文:Understanding Repository and Unit of Work Pattern and Implementing Generi ...

  7. MVC Repository模式

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

  8. (转)MVC中的Repository模式

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

  9. C# 框架是什么?MVC是什么 ?工厂模式是什么?设计模式是什么?三层架构是什

    C# 框架是什么?MVC是什么 ?工厂模式是什么?设计模式是什么?三层架构是什么?如果要学我该从何学起??? C# 框架看这里http://download.csdn.net/source/25784 ...

随机推荐

  1. 在linux中设置静态ip地址

    在linux中设置静态ip地址1.在终端中输入:vi /etc/sysconfig/network-scripts/ifcfg-eth0 2.开始编辑,填写ip地址.子网掩码.网关.DNS等[root ...

  2. CentOS利用postfix搭建邮件服务器

    之前我用nodemailer通过163邮箱来发送邮件,不过没过几天就一直ETIMEDOUT,不知道什么原因,想着还是自己搭一个来发邮件可能靠谱点(flag?) 安装postfix CentOS 7 自 ...

  3. 前端页面开发,最低兼容IE 8的多设备跨平台问题解决!

    项目要求: 网站能够使用PC.ipad.mobile phone正常访问 页面PSD版式宽度分别为1024px和750px 参考资料 使用CSS3 Media Queries,其作用就是允许添加表达式 ...

  4. PMP备考_第五章_项目范围管理_实践思考

    项目范围管理 前言 今天学习项目范围管理的内容,深切的感受到了原单位在项目管理方面存在的问题,今天在这里做一个总结,既相当于对项目范围的一个学习整理,也相当于自己对项目实践过程中存在问题的一个思考. ...

  5. php函数类型

    静态变量: <?php function calcute(){ static $num =10; $num = $num+2; echo $num."<br>"; ...

  6. 浏览器全屏事件(Html5)

    <button onclick="launchFullscreen(document.documentElement);"></button> functi ...

  7. javascript中的内置对象总结

    内置对象 标准内置对象 Object Object.create Object.prototype.toString Object.prototype.hasOwnProperty Boolean S ...

  8. Spring MVC中Session的正确用法<转>

    Spring MVC是个非常优秀的框架,其优秀之处继承自Spring本身依赖注入(Dependency Injection)的强大的模块化和可配置性,其设计处处透露着易用性.可复用性与易集成性.优良的 ...

  9. ORA-01861: 文字与格式字符串不匹配

    问题:插入数据不成功 解决:借口实现类里面的sql语句带值放到数据库中运行,如果不成功是sql语句的错误.

  10. 一个基于Orchard的开源CRM --coevery简介

    Coevery是开源的.NET Web平台项目,力争打造一个开放而鲁棒的CRM系统,采用Orchard架构,并使用AngularJS改善页面体验.作为一个后发优势的CRM 产品,Coevery 具有一 ...