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

在设计之前我理了一下自己的大致需求也参考了不同人的项目架构,在此特别感谢郭明峰的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. 客户端连接注册Ejabberd新用户

    今天需要使用客户端注册新用户,结果发现注册失败,在管理后台添加新用户成功.编译安装ejabberd就没有管了,经过翻论坛的到解决方法 在ejabberd.yml中. access: trusted_n ...

  2. [WPF] 我的WPF自学日记1,无标题窗体拖动

    学习WPF的第一天,尝试写比较常用的功能,无标题窗体拖动. 先在设计界面给它加上MouseDown事件 <Window x:Class="MyFirstWPFAPP.MainWindo ...

  3. input框focus时的美化效果

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. easyUI datagrid 根据查询条件 选中对应数据的行

    开始 输入了 土豆,南瓜,再次是小青菜,每次输入点击搜索的时候(模糊查询),选中的当前数据对应的行 在做之前,在网上查询了许多资料,也在技术群里问过许多次,弄了好久终于好了. 第一次写博客真不知道写啥 ...

  5. 浅谈WEB安全性(前端向)

    相信进来的时候你已经看到alert弹窗,显示的是你cookie信息(为配合博客园要求已删除).单纯地在你的客户端弹出信息只是类似于迫使你在自己的房间脱衣服——没人看得到,自然也不算啥恶意行为.那么如果 ...

  6. Lesson 9 A cold welcome

    Text On Wednesday evening, we went to the Town Hall. It was the last day of the year and a large cro ...

  7. CoffeeScript实现Python装潢器

    在上篇Angular遇上CoffeeScript – NgComponent封装中,我们讲述了CoffeeScript这门小巧的语言,摒弃JavaScript中糟粕(“坑”)部分,并将JavaScri ...

  8. ARM的常数表达式

    ARM的常数表达式   如果说Intel指令中的立即数,相信大家都很熟悉.类似的,Arm指令中的“立即数”就是常数表达式.之所以称为常数表达式,而不称为立即数是有原因的. Intel指令属于CISC指 ...

  9. 谈谈UI架构设计的演化

    谈谈UI架构设计的演化 经典MVC 在1979年,经典MVC模式被提出. 在当时,人们一直试图将纯粹描述思维中的对象与跟计算机环境打交道的代码隔离开来,而Trygve Reenskaug在跟一些人的讨 ...

  10. Using assembly writing algorithm programs

    This's my first version.The logic is simple, just the selection sort. I spent much time learning how ...