一直以来想本身作一套开发框架,在其基础上进行快速开发,自从接触微软的MVC框架和Entityframework以来,阅读了大量园子里的相关的技术文章,也进行了很多摸索和尝试,中间经历了屡次大刀阔斧的重构,如今总算有了雏形,把权限、模式和界面初步搞定,可是回头一看,依然有不少东西思路不够清晰,不少时候是在生搬硬套,不求甚解,结果搞出来一些四不像的东西。html
入行近十年,项目经验和开发经验应当是很丰富的,可是架构方面,确实是个新手,如今总算对相关技术有了必定的了解,所以打算从头再来一遍梳理,完全的重构。
以前参考别人的技术文章,加上本身的摸索,大体采用的模式是这样的,使用了MVC和Entityframework,Unity做为IOC容器,Model层和View层没必要多说, Controller->Service ->Repository,Repository层经过Entityframework来实现数据的增删改查,业务逻辑放在Service层,经过UnitOfWork模式来实现多实体的事务控制,Controller层的职责就是调度,处理从UI层传过来的参数转换。sql
首先来讲Repository层,首先定义了一个泛型接口,IRepository<Entity>,在里面定义了增删改查,而后定义了一个类 Repository<Entity>,实现IRepository<Entity>接口,同时为了考虑各实体特有的实现,为每一个实体定义一个特有接口,以人员为例,定义IUserRepository接口,继承IRepository<User>,最终定义类UserRepository,继承Repository<User>,并实现IUserRepository接口。数据库
全部的实体都是按照上述模式实现的,使用泛型,主要是实现了代码复用,这种模式在园子里也有很多人是这样用的。编程
关于Repository的定义和做用,园子里有不少文章提过屡次了,在此我引用下(来源): 架构
Repository是一个独立的层,介于领域层与数据映射层(数据访问层)之间。它的存在让领域层感受不到数据访问层的存在,它提供一个相似集合的接口提供给领域层进行领域对象的访问。Repository是仓库管理员,领域层须要什么东西只需告诉仓库管理员,由仓库管理员把东西拿给它,并不须要知道东西实际放在哪。 框架
因而可知,Repository是从领域驱动设计中的概念,从个人架构设计来讲,并非领域驱动的,没有聚合根的概念,对于Service层来讲,须要一个DAL层来处理数据的存储和查询,所以,我这里使用Repository明显是一个误用。spa
关于Repository与DAL 区别以下: 架构设计
Repository是DDD中的概念,强调Repository是受Domain驱动的,Repository中定义的功能要体现Domain的意图和约束,而Dal更纯粹的就是提供数据访问的功能,并不严格受限于Business层。设计
使用Repository,隐含着一种意图倾向,就是 Domain须要什么我才提供什么,不应提供的功能就不要提供,一切都是以Domain的需求为核心;而使用Dal,其意图倾向在于我Dal层能使用的数据库访问操做提供给Business层,你Business要用哪一个本身选。换一个Business也能够用我这个Dal,一切是以我Dal能提供什么操做为核心。htm
这也就意味着,不该当在DAL层单独定义一个IUserRepository类来处理特有的接口方法,如用户不能被删除,而是应当在Service层里作控制,DAL单纯地提供对数据的查询和存储,不关心业务逻辑。
明确了上面的概念,下面就动手进行简化,有两种实现方式,一是使用泛型,二是使用T4模板或者代码生成器,这两种方式都能达到代码复用的目的。我这里采用的泛型,首先定义一个泛型接口IDAO<Entity>,泛型接口中定义方法也很明确:增、删、改、查,此前在IRepository定义了过多的重载方法,例如对于删除,定义了指定主键删除、指定实体删除和指定Lambda表达式删除,对于查询,定义了返回全部实体集合和返回单页数据集合。上述概念明确后,DAL层仅须要提供必要的几个方法便可,而对于一样功能的方法重载,放到Service层更合适。而后定义EFDAO<Entity>类实现该接口。这样作的好处不只代码实现了复用,并且作到了面向接口编程,对于Service层来讲,看到的只是IDAO接口,而不是具体的实现类。而IDAO是怎么实现的,是EntityFramework、NHibernate仍是原生的sql,则能够灵活替代,变动数据访问层对整个系统无影响。
简而言之,个人框架实质是MVC模式加三层架构的结合体,View和Controller层基本不动,Model层细分为Model、Service/BLL、DAL三层。
以上是我的的反思和总结,把我的的误用经历、重构缘由和最终实现方式发出来,供同道中人参考,欢迎批评指正,期待交流。