MVC+EF+Autofac(dbfirst)轻型项目框架

前言

  原来一直使用他人的开源项目框架,异常的定位会很麻烦,甚至不知道这个异常来自我的代码还是这个框架本身。他人的框架有一定的制约性,也有可能是我对那些框架并没深入了解,因为这些开源框架在网上也很难找到高效并且规范的文档。比如别人的框架可能调用了Enterprise Library来实现权限的验证,但在我的项目中,权限验证有可以复用的模块,所以在整合时会非常不灵活。。。。

  参考了很多网上的优秀框架,看了几本书后,突然意识到易用才是开发和使用框架的出发点与立足点,框架并不是越复杂越好,评价一个框架的好坏,应综合考虑它的学习成本,使用成本和维护成本。考虑了以上因素后于是打算做一套轻量的框架出来,方便日后的扩充,虽然框架已经非常简单,但依旧可能存在着问题,希望大神们能指点迷津。

开发背景

  我所要面对的项目,并没有特别复杂的业务逻辑,需要面对的最大问题是高并发。这也是我舍弃原有的框架的重要原因。

  因为业务逻辑并不复杂,所以采用的dbfirst的设计思路,一方面是项目后续开发时他人好更容易上手,一方面是对于codefirst我也只是停留在会用的阶段,对于高深的DDD,理解还十分有限,可能会引入很多错误的思维方式。

  项目的开发环境为:Windows7 SP1、Visual Studio 2013、Sql Server 2012、.NET Framework4.5。

  项目依托ASP.NET MVC + WebAPI,数据存储采用EntityFramework。

总体框架

  这是项目解决方案的截图,从上到下分为WEB层,Core层,Model层与Infrastructure层,功能分别如下

  1. web:承载MVC以及WebAPI,负责展现
  2. Core:处理具体的业务逻辑
  3. Model:分为Entity数据实体与WebModel,WebModel主要包括WEB层与Core层数据传递的model与Web页面上的实体
  4. Infrastructure:基础实施层,存放一些可以复用的类与方法

  项目的依赖关系是这样的,使用Autofac注入。原来使用的是spring.net,这次改为更加轻量了Autofac做依赖注入,效率更高(网上说的(-:),也能找到很多的帮助文档。并且Autofac为mvc提供了以每一次请求作为注入依据的方案,将实体以参数的形式传入到控制器中,非常实用。

创建过程

  在Entity程序集中,通过数据库生成edmx,这里面也包含了实体对象的模型。接下来就要在core中创建Entities的DbContext实体。

  在我原来的系统中,我一般会在EF上在创建一个DAL(数据库访问层),用来存放常用的增删改查的方法,但后来逐渐体会到EF框架本身其实已经很好地封装好了传统DAL层中的方法,如果在放一个DAL层就有重复封装之嫌。这里就不详细讨论这层DAL封装是否有必要,因为不同的人的习惯会不同,如果你是传统三层过来的,也许放个DAL会更得心应手些,当然不放也有不放的好处,比如业务在操作数据库时可以更加灵活,编码时少了层接口也可以显得更加直观。但是不加DAL无法对数据库的操作进行封装,从而应运而生了另一个看似比较棘手的问题,如果日后变更数据库,需要变更core层中的代码吗?这将导致高耦合。这个问题我当初也纠结了很久,但转过来一想,Entity framework是一个开源框架,对主流数据库包括oracle等都已支持,变更数据库只需要重新生成对应数据库类型的edmx,对业务core是没有影响的。

  我在业务层创建了一个CoreSession类,用来存放给web的业务操作的集合。

  下面是接口,定义了一个公共的savechanges方法,至于干嘛用,我后面会说。

1     public interface ICoreSession
2     {
3         int SaveChanges();4     }

  下面是实现,里面有一个db属性,存放实例后的Entity对象,并最构造方法中新建实例。

 1  public class CoreSession:EDUA_ICore.ICoreSession
 2     {
 3         private DbContext db { get; set; }
 4         public CoreSession()
 5         {
 6             db = new Entity.EDUAEntities();
 7         }
 8         public int SaveChanges()
 9         {
10            return db.SaveChanges();
11         }
12     }

  一个最简单的core层构建完成了,虽然里面暂时没有任何的方法。接下来要在web层中创建core对象。那么core在web层中能否单例呢?core的单例也就意味着EF实体的单例,因为EF的实例过程在core的构造方法中。而EF本身是不能保证线程安全的。那天在和前辈们讨论EF该不该单例这个问题时,几乎两人同时告诉我千万不要,他们都中过招,如果用最简单的static来实现single,不仅仅是高并发,而是只要并发时就会出问题。当然有另一种方法,用callcontext将core对象放入线程中,每次用时从线程中取,用这种方法来保证EF的线程安全性,这是我用过的一种较靠谱的单例方法,而且暂时还没出过什么问题。但为了保证高并发时的性能,并且借鉴Autofac(Ioc)所提供的机制,我决定采用为每一次请求创建一个Core对象。

  我配置Autofac的过程如下

  1.下载并引入Autofac的程序集

    下载地址:http://autofac.org/

这里需要在WEB引入这两个程序集,前者是autofac的核心,后者是它的mvc插件,如果需要将注入的映射对象写到配置文件里,还需要引入Autofac.Configuration.dll 这个程序集,由于我直接将映射写在了代码中,所以没有引。

2.在web层中创建RegisterAutofacForSingle类,虽然名字说是single,但只是注册时的single,并不是说将对象单例了。  

 1     public class RegisterAutofacForSingle
 2     {
 3         public static void RegisterAutofac()
 4         {
 5             ContainerBuilder builder = new ContainerBuilder();
 6             builder.RegisterControllers(Assembly.GetExecutingAssembly());
 7
 8             //注册给控制器
 9             builder.RegisterType<EDUA_Core.CoreSession>().As<EDUA_ICore.ICoreSession>().InstancePerHttpRequest();
10
11             //注册给过滤器
12             builder.RegisterType<EDUA_Core.CoreSession>().As<EDUA_ICore.ICoreSession>();
13             builder.RegisterType<Filters.MyAuthorizeAttribute>().SingleInstance();
14             builder.RegisterFilterProvider();
15
16             var container = builder.Build();
17             DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
18         }
19
20     }

第6行注册了控制器的版本,第9行的方法InstancePerHttpRequest()为每一个新的请求创建一个新实例,后面注册给过滤器的行为中,是全局单例的,因为我的过滤器中不会存在写的操作,不存在并发时的读写问题。

3.在Globa.asax文件中注册Autofac

 1     public class MvcApplication : System.Web.HttpApplication
 2     {
 3         protected void Application_Start()
 4         {
 5             //注册Autofac
 6             RegisterAutofacForSingle.RegisterAutofac();
 7
 8             AreaRegistration.RegisterAllAreas();
 9
10             WebApiConfig.Register(GlobalConfiguration.Configuration);
11             FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
12             RouteConfig.RegisterRoutes(RouteTable.Routes);
13             BundleConfig.RegisterBundles(BundleTable.Bundles);
14         }
15     }

需要注意的是,由于RegisterAutofacForSingle中给过滤器注册了注入,所以注册Autofac需要放在注册过滤器之前,不然会报错。我把Autofac的注册放在了最前面。

  4.在控制器与过滤器中添加core对象实例

1         private ICoreSession iCoreSession;
2         public MyAuthorizeAttribute(ICoreSession iCoreSession)
3         {
4             this.iCoreSession = iCoreSession;
5         } 

  至此, 在控制器和过滤器中就都可以直接调用到core中的内容了。

  在接下去的文章中我会举一个登陆的例子来扩充core层,并且在过滤器中实现权限的判断。

时间: 2024-11-17 06:07:47

MVC+EF+Autofac(dbfirst)轻型项目框架的相关文章

2_MVC+EF+Autofac(dbfirst)轻型项目框架_用户权限验证

前言 接上面两篇 0_MVC+EF+Autofac(dbfirst)轻型项目框架_基本框架 与 1_MVC+EF+Autofac(dbfirst)轻型项目框架_core层(以登陆为例) .在第一篇中介绍了此架构的基本分层,在第二篇中,以登陆功能为例,介绍了项目的代码结构.在本篇中将通过过滤器实现用户权限验证功能. 同样,文中有问题的地方欢迎批评指正!谢谢! 开发背景  在一个常规系统中权限验证是不可缺的,在较简单的系统中,用户只会被简单归为登陆用户和游客,而在较为复杂的系统中,除了判断用户是否登

1_MVC+EF+Autofac(dbfirst)轻型项目框架_core层(以登陆为例)

前言 在上一篇0_MVC+EF+Autofac(dbfirst)轻型项目框架_基本框架中,我已经介绍了这个轻型框架的层次结构,在下面的这篇文章中,我将以教师登陆功能为例,具体来扩充下我的core层的代码. 在这之前,我想先补充讨论下是否有必要添加server层,因为看过不少别人的框架都有这一层.首先,server层在不同地方有着不同的解释.有个常听的词叫MVSC,这里所指的S虽然也是server的意思,但实现的功能更有点类似于我框架中的core,主要存放也是业务逻辑.但我看了别人框架上的serv

MVC5+EF+AutoFac+AutoMapper轻型架构

今天和大家一起学习一下当前流行的MVC5+EF+AutoFac+AutoMapper轻型架构,先上一张框架图 一.项目基本框架搭建 写程序的顺序是Model-DAL-BLL-UI,Model层就是表实体,我们略过,下面上DAL层代码 using Model; using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; usi

多层架构+MVC+EF+AUTOFAC+AUTOMAPPER【转】

多层架构+MVC+EF+AUTOFAC+AUTOMAPPER 最近使用ligerui搭建了一个简单的教务管理demo,将重要的地方记录,也希望能帮到有这方面需要园友. 一.目录 1.多层架构+MVC+EF+AUTOFAC+AUTOMAPPER: 2.MVC中验证码的实现(经常用,记录备用) 二.正文 多层架构中等以上规模以上的系统用得比较多,此demo功能不多,出于抱着学习的态度搭建了一个多层架构,并加入现在很流行的依赖倒转(autofac).对象映射工具(automapper). 话说没图你说

多层架构+MVC+EF+AUTOFAC+AUTOMAPPER

最近使用ligerui搭建了一个简单的教务管理demo,将重要的地方记录,也希望能帮到有这方面需要园友. 一.目录 1.多层架构+MVC+EF+AUTOFAC+AUTOMAPPER: 2.MVC中验证码的实现(经常用,记录备用) 二.正文 多层架构中等以上规模以上的系统用得比较多,此demo功能不多,出于抱着学习的态度搭建了一个多层架构,并加入现在很流行的依赖倒转(autofac).对象映射工具(automapper). 话说没图你说个J8,先上框架图: Model层中Entity存放数据库实体

MVC+EF三层+抽象工厂项目搭建

注意:项目经过两次搭建,所以截图中顶级命名空间有ZHH和ZHH2区别,但是架构的内容是一样的,可以将ZHH和ZHH2视为同一命名空间 一:权限管理 二:搜索 |-Lucene.net(速度快)+盘古分词(搜索词拆分)---比模糊查询更模糊 |-模糊查询like效率慢,全盘扫描,不能拆分 盘古分词,分出来的词,用文件存在磁盘内 ,文件并发 ----lock锁->新的问题,效率慢,用户需要等待 生产者消费者模式---优化文件并发 把分词放在队列中(内存集合中),Redis分布式队列 *sesion只

分享基于.NET MVC+EF CodeFirst+IOC+EasyUI的框架设计

**注:要做工,没什么时间,等有空时会上传到GIT,项目结构如上,简单的说一下: **支持IOC及多数据库等,各项目由MVC区域隔离: 主要使用基于接口与抽象类进行高度的抽象与接口隔离,与其它框架比较优点如下: 1,抽象度非常高,接口隔离,项目清晰完整,任何一部分均可且容易替换:一开始就非常注重非陷入复杂化: 2,框架非常易用,且易于扩展:编程新手也可立即上手使用: 3,设计目标为:轻量化.高抽象度.可扩展性.模块任意替换.清晰简洁易用(易懂.代码量要少[没必要码农]): **NetDevelo

22、ASP.NET MVC入门到精通——搭建项目框架

本系列目录:ASP.NET MVC4入门到精通系列目录汇总 前面的章节,说了ASP.NET MVC项目中常用的一些技术和知识点,更多的是理论上面的东西,接下来,我将通过一个简单的OA项目来应用我们之前涉及到的一些技术,为了兼顾初学者,所以我尽量把操作步骤说得足够详细.(本来想用VS2015来演示MVC5开发的,无奈家里的笔记本是11年2月份的老爷机了,一直未曾舍得换,因为配置的缘故,笔记本不堪负重,难以安装最新版本的开发工具,只装了VS2012,当然,还有一个原因就是现在公司也是使用VS2012

.NET框架 - NETFramework + API + EF(DBFirst) + MYSQL

.NET框架 - NETFramework + MVC+ EF(DBFirst) + MYSQL 1. 安装3个MYSQL插件 ①mysql-for-visualstudio-1.2.8    vs的mysql工具  官网下载链接 ②mysql-connector-net-6.10.8   注意版本号 必须与项目代码中的MySql.Data.Entity 的版本保持一致,否则在实体选择的时候闪退    官网下载链接 ③mysql-connector-odbc-5.3.10-winx64