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

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

最近使用ligerui搭建了一个简单的教务管理demo,将重要的地方记录,也希望能帮到有这方面需要园友。



一、目录

 1、多层架构+MVC+EF+AUTOFAC+AUTOMAPPER;

 2、MVC中验证码的实现(经常用,记录备用)

二、正文

 多层架构中等以上规模以上的系统用得比较多,此demo功能不多,出于抱着学习的态度搭建了一个多层架构,并加入现在很流行的依赖倒转(autofac)、对象映射工具(automapper)。

 话说没图你说个J8,先上框架图:

  Model层中Entity存放数据库实体,使用code first,ViewModel存放界面展示模型。DAL层中IDAO存放接口,EFDAO 实现IDAO。BLL结构与DAL类似,接口+实现。WEB层就是我们的UI层了,在这个框架中,WEB层使用MVC。什么,MVC不就是多层架构嘛,怎 么还把它放Web层呢?MVC并不等同于多层架构,有这样疑问的同学,请在园内搜索相关文章。Infrastructure层是我们的基础设施层,我把一 些常用的工具类封装后放入其中,方便其它地方调用。

  IDao中定义了一个公共基类,基类中定义所有子类都会用到的查询方法:

 1 namespace YTJWGL_IDao
 2 {
 3     public interface IBaseDao<T>
 4     {
 5         #region 查询普通实现方案(基于Lambda表达式的Where查询)
 6         /// <summary>
 7         /// 获取所有Entity
 8         /// </summary>
 9         /// <param name="exp">Lambda条件的where</param>
10         /// <returns></returns>
11         IEnumerable<T> GetEntities(Func<T, bool> exp);
12
13         /// <summary>
14         /// 计算总个数(分页)
15         /// </summary>
16         /// <param name="exp">Lambda条件的where</param>
17         /// <returns></returns>
18         int GetEntitiesCount(Func<T, bool> exp);
19
20         /// <summary>
21         /// 分页查询(Linq分页方式)
22         /// </summary>
23         /// <param name="pageNumber">当前页</param>
24         /// <param name="pageSize">页码</param>
25         /// <param name="orderName">lambda排序名称</param>
26         /// <param name="sortOrder">排序(升序or降序)</param>
27         /// <param name="exp">lambda查询条件where</param>
28         /// <returns></returns>
29         IEnumerable<T> GetEntitiesForPaging(int pageNumber, int pageSize, Func<T, string> orderName, string sortOrder, Func<T, bool> exp);
30
31         /// <summary>
32         /// 根据条件查找
33         /// </summary>
34         /// <param name="exp">lambda查询条件where</param>
35         /// <returns></returns>
36         T GetEntity(Func<T, bool> exp);
37
38         #endregion
39
40         //#endregion
41         /// <summary>
42         /// 插入Entity
43         /// </summary>
44         /// <param name="model"></param>
45         /// <returns></returns>
46         bool Insert(T entity);
47         /// <summary>
48         /// 更新Entity
49         /// </summary>
50         /// <param name="model"></param>
51         /// <returns></returns>
52         bool Update(T entity);
53         /// <summary>
54         /// 删除Entity
55         /// </summary>
56         /// <param name="entity"></param>
57         /// <returns></returns>
58         bool Delete(T entity);
59         /// <summary>
60         /// 删除实现 存储过程实现方式(调用spDelete+表名+ 主键ID)
61         /// </summary>
62         /// <param name="ID">删除的主键</param>
63         /// <returns></returns>
64         //bool Delete(object ID);
65     }
66 }
 

IDAO

  EFDao有一个类实现这一公共基类:

 1 namespace YTJWGL_EFDao
  2 {
  3     public class BaseEFDao<T> : IBaseDao<T> where T : class,new()//限制T的类型为class或者对象
  4     {
  5
  6
  7         #region 查询普通实现方案(基于Lambda表达式的Where查询)
  8         /// <summary>
  9         /// 获取所有Entity
 10         /// </summary>
 11         /// <param name="exp">Lambda条件的where</param>
 12         /// <returns>返回IEnumerable类型</returns>
 13         public virtual IEnumerable<T> GetEntities(Func<T, bool> exp)
 14         {
 15             using (Entities db = new Entities())
 16             {
 17                 return db.Set<T>().Where(exp).ToList();
 18             }
 19
 20
 21         }
 22         /// <summary>
 23         /// 计算总个数(分页)
 24         /// </summary>
 25         /// <param name="exp">Lambda条件的where</param>
 26         /// <returns></returns>
 27         public virtual int GetEntitiesCount(Func<T, bool> exp)
 28         {
 29             using (Entities db = new Entities())
 30             {
 31                 return db.Set<T>().Where(exp).ToList().Count();
 32
 33             }
 34         }
 35         /// <summary>
 36         /// 分页查询(Linq分页方式)
 37         /// </summary>
 38         /// <param name="pageNumber">当前页</param>
 39         /// <param name="pageSize">页码</param>
 40         /// <param name="orderName">lambda排序名称</param>
 41         /// <param name="sortOrder">排序(升序or降序)</param>
 42         /// <param name="exp">lambda查询条件where</param>
 43         /// <returns></returns>
 44         public virtual IEnumerable<T> GetEntitiesForPaging(int pageNumber, int pageSize, Func<T, string> orderName, string sortOrder, Func<T, bool> exp)
 45         {
 46             using (Entities db = new Entities())
 47             {
 48                 if (sortOrder == "asc") //升序排列
 49                 {
 50                     return db.Set<T>().Where(exp).OrderBy(orderName).Skip((pageNumber - 1) * pageSize).Take(pageSize).ToList();
 51                 }
 52                 else
 53                 {
 54                     return db.Set<T>().Where(exp).OrderByDescending(orderName).Skip((pageNumber - 1) * pageSize).Take(pageSize).ToList();
 55                 }
 56             }
 57
 58         }
 59         /// <summary>
 60         /// 根据条件查找满足条件的一个entites
 61         /// </summary>
 62         /// <param name="exp">lambda查询条件where</param>
 63         /// <returns></returns>
 64         public virtual T GetEntity(Func<T, bool> exp)
 65         {
 66             using (Entities db = new Entities())
 67             {
 68                 return db.Set<T>().Where(exp).SingleOrDefault();
 69             }
 70         }
 71         #endregion
 72
 73         #region 增改删实现
 74         /// <summary>
 75         /// 插入Entity
 76         /// </summary>
 77         /// <param name="model"></param>
 78         /// <returns></returns>
 79         public virtual bool Insert(T entity)
 80         {
 81             using (Entities db = new Entities())
 82             {
 83                 var obj = db.Set<T>();
 84                 obj.Add(entity);
 85                 return db.SaveChanges() > 0;
 86
 87             }
 88
 89         }
 90         /// <summary>
 91         /// 更新Entity(注意这里使用的傻瓜式更新,可能性能略低)
 92         /// </summary>
 93         /// <param name="model"></param>
 94         /// <returns></returns>
 95         public virtual bool Update(T entity)
 96         {
 97             using (Entities db = new Entities())
 98             {
 99                 var obj = db.Set<T>();
100                 obj.Attach(entity);
101                 db.Entry(entity).State = System.Data.EntityState.Modified;
102                 return db.SaveChanges() > 0;
103             }
104
105
106         }
107         /// <summary>
108         /// 删除Entity
109         /// </summary>
110         /// <param name="entity"></param>
111         /// <returns></returns>
112         public virtual bool Delete(T entity)
113         {
114             using (Entities db = new Entities())
115             {
116                 var obj = db.Set<T>();
117                 if (entity != null)
118                 {
119                     obj.Attach(entity);
120                     db.Entry(entity).State = System.Data.EntityState.Deleted;
121                     obj.Remove(entity);
122                     return db.SaveChanges() > 0;
123                 }
124                 return false;
125             }
126
127         }
128         #endregion
129     }
130 }

EFDAO

  可以看到,代码中都是使用的泛型。根据传入的实体类型决定访问莫一数据实体。

  倘若,我们有一个数据实体类叫做Admin,IDAO,EFDAO中可以分别添加Admin对应的DAL层文件:

IAdminDao

1 namespace YTJWGL_EFDao
2 {
3     public class AdminEFDao : BaseEFDao<YTJWGL_Admin>, IAdminDao<YTJWGL_Admin>
4     {
5     }
6 }
AdminEFDao

   IAdminDao继承我们上面定义的 公共接口,AdminEFDao继承IAdminDao接口以及BaseEFDao基类,这样我们可以在IAdminDao中定义该数据实体特有的查询方 法,同时复用了我们常用的查询以及增加、删除、编辑代码。至于为什么要使用接口,是为了满足面向对象原则的依赖倒转原则——抽象不依赖细节,细节应该依赖 抽象。

  BLL层代码结构与DAL类似。

  一个简单的多层架构就是这样,各层之间引用关系从顶层向下调用底层,将各层之间耦合尽量降低。



  然后,谈谈配置autofac。

  这里,发现这工具很好,很强大,至于有多强大,我也不清楚,因为我也很菜(/ □ \)……

  autofac配置园里相关文章也很多,我这里就初略的说说。

  First step:nuget上加入我们autofac的程序集引用:

  

  注意,根据你所使用的.net环境选择相应的程序集,目前最新的版本是3.1.0,低版本的autofac是不支持.net4.0的。我们这里使用了MVC4.0所以选择第二个。

  Second step:配置依赖注入,说白了就是告诉autofac你要将哪个类与接口“发生关系”。

  

  在这个框架中,我们将配置信息在图示类中完成:

namespace YTJWGL_WebUI.RegisterAutofac
{
    public static class RegisterAutofacForSingle
    {
        public static void RegisterAutofac()
        {
            ContainerBuilder builder = new ContainerBuilder();
            builder.RegisterControllers(Assembly.GetExecutingAssembly());

            #region IOC注册区域
            //倘若需要默认注册所有的,请这样写(主要参数需要修改)
            //builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
            //   .AsImplementedInterfaces();

            //Admin
            builder.RegisterType<AdminService>().As<IAdminService>().InstancePerHttpRequest();

            #endregion
            // then
            var container = builder.Build();
            DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

        }

    }
}
RegisterAutofacForSingle

  autofac有很多重配置方式,详询此处:http://www.cnblogs.com/hkncd/archive/2012/11/28/2792474.html

  好了,下面我们在全局文件Global.asax中调用刚才定义的方法:

1 namespace YTJWGL_WebUI
 2 {
 3     // Note: For instructions on enabling IIS6 or IIS7 classic mode,
 4     // visit http://go.microsoft.com/?LinkId=9394801
 5     public class MvcApplication : System.Web.HttpApplication
 6     {
 7         protected void Application_Start()
 8         {
 9             AreaRegistration.RegisterAllAreas();
10
11             WebApiConfig.Register(GlobalConfiguration.Configuration);
12             FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
13             RouteConfig.RegisterRoutes(RouteTable.Routes);
14
15             //autofac注册
16             RegisterAutofacForSingle.RegisterAutofac();

18
19             //automapper注册
20             RegisterAutomapper.Excute();
21         }
22     }
23 }
Global.asax

  至此,autofac的配置就基本OK。其是用也比较的方便,autofac是使用构造函数注入:



 1 namespace YTJWGL_WebUI.Areas.Admin.Controllers
 2 {
 3
 4     public class FrameController : Controller
 5     {
 6         //
 7         // GET: /Admin/Frame/
 8         #region Fields
 9
10         private readonly IAdminService _adminService;
11
12         #endregion
13
14         #region Constructors
15
16         public FrameController(IAdminService adminService)
17         {
18             this._adminService = adminService;
19         }
20         #endregion
21
22         #region Admin
23
24         [HttpPost]
25         public ActionResult Login(LoginModel model, string returnUrl)
26         {
27          //这样调用
28            var amin = _adminService.GetAllEntities(p => p.ID != 0);
29         }
36     }
37 }
FrameController

  这样就可以使用接口调用方法了。autofac简单配置完毕。



  接下来我们配置automapper:

  First Step:与autofac同样的方法在nuget里面安装。

  Secoud Step:

   

  我把automapper分为两部配置,第一步与autofac类似,首先注册,也就是告诉automapper组件,你要在哪两个Model之间映射:

 1 namespace YTJWGL_WebUI.Automapper
 2 {
 3     public static class RegisterAutomapper
 4     {
 5         public static void Excute()
 6         {
 7
 8             //Admin
 9             Mapper.CreateMap<LoginModel, YTJWGL_Admin>();
10             Mapper.CreateMap<YTJWGL_Admin, LoginModel>().ForMember(dest => dest.ValidatorCode, sor => sor.Ignore());
11
12         }
13
14     }
15 }

RegisterAutomapper

 代码中Formeber后面的代码可以不要,详情在这:http://www.cnblogs.com/ljzforever/archive/2011/12/29/2305500.html;

  然后看看我们第二个文件MapperExtention:

 1 namespace YTJWGL_WebUI.Automapper
 2 {
 3     public static class MapperExtention
 4     {
 5         #region Admin
 6
 7        public static AdminModel ToModel(this YTJWGL_Admin entity)
 8         {
 9             return Mapper.Map<YTJWGL_Admin, AdminModel>(entity);
10         }
11
12         public static YTJWGL_Admin ToEntity(this AdminModel model)
13         {
14             return Mapper.Map<AdminModel, YTJWGL_Admin>(model);
15         }
16
17         public static YTJWGL_Admin ToEntity(this AdminModel model, YTJWGL_Admin destination)
18         {
19             return Mapper.Map<AdminModel, YTJWGL_Admin>(model, destination);
20         }
21
22     }
23 }
MapperExtention中定义了一个个拓展方法,添加这个文件会让我们在控制器中映射实体变得非常方便:
 public ActionResult List()
2         {
3             //数据库实体向ViewModel转换
4             var model = _newsService.GetEntityByQuery(p => p.ID == 1).ToModel();
5             //ViewModel向数据库实体转换
6             var entity = model.ToEntity();
7             return View();
8         }

  就向调用ToString()方法一样的使用。

  当然,我们的automapper还需要在Global文件中调用,这一步在autofac最后一张图中已经说明。

时间: 2024-10-21 14:33:27

多层架构+MVC+EF+AUTOFAC+AUTOMAPPER【转】的相关文章

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

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

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(dbfirst)轻型项目框架

前言 原来一直使用他人的开源项目框架,异常的定位会很麻烦,甚至不知道这个异常来自我的代码还是这个框架本身.他人的框架有一定的制约性,也有可能是我对那些框架并没深入了解,因为这些开源框架在网上也很难找到高效并且规范的文档.比如别人的框架可能调用了Enterprise Library来实现权限的验证,但在我的项目中,权限验证有可以复用的模块,所以在整合时会非常不灵活.... 参考了很多网上的优秀框架,看了几本书后,突然意识到易用才是开发和使用框架的出发点与立足点,框架并不是越复杂越好,评价一个框架的

.NET跨平台之mac 下vs code 多层架构编程

合肥程序员群:49313181.    合肥实名程序员群:128131462 (不愿透露姓名和信息者勿加入,申请备注填写姓名+技术+工作年限) Q  Q:408365330     E-Mail:[email protected] 概述: 为了研究跨平台.NET 开发,我打算利用.NET core 编写一个跨平台的cms,这个CMS我也秉着开源的原则放到github上面,为.NET 开源社区做点小小的贡献吧.如果有兴趣的可以联系我一起为.NET开源和跨平台做点小小的贡献吧.EgojitCMS传送

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

ASP.NET MVC+EF框架+EasyUI实现权限管理系列

http://www.cnblogs.com/hanyinglong/archive/2013/03/22/2976478.html ASP.NET MVC+EF框架+EasyUI实现权限管理系列之开篇 前言:博客又有一段时间没有更新了,心里感觉这段时间空空的,好像什么都没有学下,所以就想写博客,所以就有了这个系列,这里当然也要感谢大家了,因这个 项目我已经上传了,得到了很多网友的评价,也有好多人发邮件给我说这个框架容易出现问题,不能访问,这也是支持我写这个系列的动力,我将这个项目写成一个 系列

关于多层架构一些思考

1:关于多层架构(N-Tier) 多层架构是一种被行业证明过的软件架构模型,对开发一些解决可扩展性.安全性.容 错性方面的企业级(客户端/服务端)应用程序支持是相当给力.但在.NET世界里,我们有许多工具和产品,却没有指导手册是关于如何设计和实现一个良好的 多层架构模型,比如一些样例版,Demo等等,我们或许多少有听到.看到一些关于多层架构模型的用途和益处,但更多知道的仅仅是如何使用和实现,没有过多 的思考为何我们要这样设计呢?这样设计符合了哪些设计模式呢?遵循哪些设计原则呢?或者了解一点多层的

ASP.NET MVC+EF框架+EasyUI实现权限管理

4.为什么使用MVC而不是用WebForm呢? (1)为什么使用MVC而不是用WebForm呢?这个是我临时想的,因为我就是想说明一下WebForm和MVC的优缺点,来可以使大家能够更好地理解 MVC和WebForm,而不像某些人说MVC会替代WebForm,我个人认为这个可能性很小,因为各有各的好处,看在哪里使用吧,下面我就简单介绍下 WebForm和MVC的优缺点. (2)WebForm介绍 1)优点 1):支持事件模型,取决于微软提供了丰富的服务器端组建,WebForm可以快速的搭建Web