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

在设计之前我理了一下自己的大致需求也参考了不同人的项目架构,在此特别感谢郭明峰的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. STM32之输入捕获以及小小应用(库)

    五一之际,先祝大家五一快乐.其实快乐很简单,工作的人有假放,学习的人也有假放,像我,有假放才有更多的时间学自己想学的东西.51假期学51,可惜没有32假期呀.好了..言归正传,大家听过吸星大法吧..在 ...

  2. 李洪强iOS经典面试题153- 补充

    李洪强iOS经典面试题153- 补充   补充 有空就来解决几个问题,已经懒癌晚期没救了... UML 统一建模语言(UML,UnifiedModelingLanguage)是面向对象软件的标准化建模 ...

  3. spring和Hibernate整合

    首先导入spring和Hibernate的jar包,以及JDBC和c3p0的jar包, 然后就是Hibernate的XML配置文件,不需要加入映射文件,这里用spring容器管理了. Hibernat ...

  4. *HDU 1115 计算几何

    Lifting the Stone Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others ...

  5. 文件过滤驱动框架Minispy解析一

    因工作需要,研究minispy文件过滤框架,上图为我整理出的其内核部分代码的逻辑.

  6. 编写一个基本的连接池来实现连接的复用&一些工程细节上的优化

    package it.cast.jdbc; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQL ...

  7. spark 笔记

    官网 http://spark.apache.org/ 安装:http://dblab.xmu.edu.cn/blog/spark-quick-start-guide/ 教程 http://www.c ...

  8. UI控件(UISegmentedControl)

    @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; NSArray* segmentArray = [[ ...

  9. Hadoop学习笔记—2.不怕故障的海量存储:HDFS基础入门

    一.HDFS出现的背景 随着社会的进步,需要处理数据量越来越多,在一个操作系统管辖的范围存不下了,那么就分配到更多的操作系统管理的磁盘中,但是却不方便管理和维护—>因此,迫切需要一种系统来管理多 ...

  10. Asp.Net MVC 分页、检索、排序整体实现

    很多时候需要这样的功能,对表格进行分页.排序和检索.这个有很多实现的方式,有现成的表格控件.用前端的mvvm,用户控件.但很多时候看着很漂亮的东西你想进一步控制的时候却不那么如意.这里自己实现一次,功 ...