ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

大鹏一日同风起,扶摇直上九万里。这篇文章主要讲述ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)相关的知识,希望能为你提供帮助。
之前在园子闲逛的时候,发现许多关于automapper的文章,以及用aotufac+automapper合在一起用。当然发现大多数文章是将automapper的特点说出或将automapper几处关键代码放出。当然有过基础的人看这种文章没有什么问题,但是对于完全没有基础的小白来看完全是灾难级别的(我就是),经常按着博文一点一点的写,突然发现少了一部分导致代码无法运行。在搜索各种文章之后,终于用自己的理解写出了一个简单的运用automapper的demo,日后待我对automapper理解加深会进一步更新。【此文章希望对想能初步运用automapper的小白写出。当然也希望各位大牛提出意见】(关于autofac详细讲解)
0】首先看看automapper的介绍吧:
automapper是对象到对象的映射工具。在完成映射规则之后,automapper可以将源对象转换为目标对象。
1】首先放出项目结构图【ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)】

ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

文章图片

由于此demo运用的是mvc三层+autofac实现依赖注入,所以文件中有三层以及ui层app_Start下的autoFacConfig.cs文件。之前有一篇博文详细讲解了autofac,所以这里只是简单介绍一下代码。主要目光放在mode层和automapper相关的文件。
2】首先贴出各层代码model文件下结构
ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

文章图片

可以看到model文件夹下有两个内库autoTS.Model和autoTS.ModelView(其实autoTS.ModelView下文件可以放到autoTS.Model中,刚刚写的时候忘记了)
autoTS.Mode中system文件夹中文件是和数据库中表一一对应。而autoTS.ModelView下system中文件则是和autoTS.Mode中system文件夹中文件对应(为了实现automapper的功能)将两者进行对比一下
ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

文章图片

ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

文章图片

 
可以看到两者的不同,明显负责连接数据库的model彼modelView多了一些标志(上传csdn中代码的时候忘记写这些,可以下载demo和阅读此博客)
然后autoTs.model层下DBContext.cs代码(autoTS.Model层需要在nuget中引用EntityFramework)
ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

文章图片
ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

文章图片
public class DBContext : DbContext {public DBContext() : base("name=DatabaseTS") { }//配置文件中连接数据库设置的name public DbSet< User> User { get; set; }public DbSet< UserType> UserType { get; set; } }

View Code 3】接下来是DAL文件的结构以及代码(不是本文章主要内容值贴出代码,不加以详细说明)
ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

文章图片

先是idal层中的文件代码(需要nuget中引用EntityFramework 和autoTS.Model)
IBaseDal.cs
ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

文章图片
ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

文章图片
//具体业务依赖于接口 public interface IBaseDal< TEntity> where TEntity : class { #region 1.0 增void Add(TEntity model); #endregion#region 2.0 删void Delete(TEntity model, bool isAddedDbContext); #endregion#region 3.0 改void Edit(TEntity model, string[] propertyNames); #endregion#region 4.0 查#region 4.0.1 根据条件查询List< TEntity> QueryWhere(Expression< Func< TEntity, bool> > where); #endregion #endregion#region 5.0 统一保存/// < summary> /// 统一将EF容器对象中的所有代理类生成相应的sql语句发给db服务器执行 /// < /summary> /// < returns> < /returns> int SaveChanges(); #endregion}

View Codesystem中User_IDAL.cs
ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

文章图片
ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

文章图片
public interface User_IDAL : IBaseDal< User> { }

View Code 
然后是dal层中的代码(需要引用EntityFramework 和autoTS.Model、autoTS.IDAL)
BaseDal.cs
ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

文章图片
ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

文章图片
public class BaseDal< TEntity> : IBaseDal< TEntity> where TEntity : class { //1.0实例化EF上下文 DbContext db = BaseDBContent.GetCurrentThreadInstance(); //2.0 定义DbSet< T> 对象 public DbSet< TEntity> _dbset; //3.0 在构造函数的初始化_dbset public BaseDal() { _dbset = db.Set< TEntity> (); }#region 1.0 增public virtual void Add(TEntity model) { //1.0 参数合法性验证 if (model == null) { throw new Exception("BaseRepository泛型类中,新增操作的实体不能为空"); }//2.0 进行新增操作 _dbset.Add(model); }#endregion#region 2.0 删public virtual void Delete(TEntity model, bool isAddedDbContext) { //1.0 参数合法性验证 if (model == null) { throw new Exception("BaseRepository泛型类中,删除操作的实体不能为空"); }//2.0 进行删除逻辑处理 if (!isAddedDbContext) { _dbset.Attach(model); }_dbset.Remove(model); }#endregion#region 3.0 改/// < summary> /// 编辑,约定model 是一个自定义的实体,没有追加到EF容器中的 /// < /summary> /// < param name="model"> < /param> public virtual void Edit(TEntity model, string[] propertyNames) { //0.0 关闭EF的实体属性合法性检查 db.Configuration.ValidateOnSaveEnabled = false; //1.0 参数合法性验证 if (model == null) { throw new Exception("BaseRepository泛型类中,编辑操作的实体不能为空"); }if (propertyNames == null || propertyNames.Length == 0) { throw new Exception("BaseRepository泛型类中,编辑操作的属性数组必须至少有一个值"); }//2.0 将model追加到EF容器中的 DbEntityEntry entry = db.Entry(model); entry.State = EntityState.Unchanged; foreach (var item in propertyNames) { entry.Property(item).IsModified = true; } }#endregion#region 4.0 查/// < summary> /// 带条件查询 /// < /summary> /// < param name="where"> < /param> /// < returns> < /returns> public virtual List< TEntity> QueryWhere(Expression< Func< TEntity, bool> > where) { return _dbset.Where(where).ToList(); } #endregion#region 5.0 统一保存/// < summary> /// 统一将EF容器对象中的所有代理类生成相应的sql语句发给db服务器执行 /// < /summary> /// < returns> < /returns> public virtual int SaveChanges() { try { return db.SaveChanges(); } catch (Exception ex) { throw ex; } }#endregion}

View CodeBaseDBContent.cs
ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

文章图片
ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

文章图片
public class BaseDBContent {//获取当前EF上下文的唯一实例 public static DbContext GetCurrentThreadInstance() { DbContext obj = CallContext.GetData(typeof(BaseDBContent).FullName) as DbContext; if (obj == null) { obj = new DBContext(); CallContext.SetData(typeof(BaseDBContent).FullName, obj); } return obj; } }

View Codesystem中User_DAL.cs
ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

文章图片
ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

文章图片
public class User_DAL : BaseDal< User> , User_IDAL { }

View Code 4】bll文件中代码和结构
ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

文章图片

 
ibll层代码(此层需要引用autoTS.Model)
IBaseBLL.cs
ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

文章图片
ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

文章图片
public interface IBaseBLL< TEntity> where TEntity : class { #region 1.0 增void Add(TEntity model); #endregion#region 2.0 删void Delete(TEntity model, bool isAddedDbContext); #endregion#region 3.0 改/// < summary> /// 编辑,约定model 是一个自定义的实体,没有追加到EF容器中的 /// < /summary> /// < param name="model"> < /param> void Edit(TEntity model, string[] propertyNames); #endregion#region 4.0 查/// < summary> /// 带条件查询 /// < /summary> /// < param name="where"> < /param> /// < returns> < /returns> List< TEntity> QueryWhere(Expression< Func< TEntity, bool> > where); #endregion#region 5.0 统一保存/// < summary> /// 统一将EF容器对象中的所有代理类生成相应的sql语句发给db服务器执行 /// < /summary> /// < returns> < /returns> int SaveChanges(); #endregion}

View Codesystem文件夹下User_IBLL.cs
ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

文章图片
ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

文章图片
public interface User_IBLL : IBaseBLL< User> { }

View Code 
bll层中代码(需要引用autoTS.Model、autoTS.IBLL、autoTS.IDAL)
BaseBLL.cs
ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

文章图片
ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

文章图片
public class BaseBLL< TEntity> : IBaseBLL< TEntity> where TEntity : class { protected IBaseDal< TEntity> dal = null; #region 1.0 增public virtual void Add(TEntity model) { dal.Add(model); }#endregion#region 2.0 删public virtual void Delete(TEntity model, bool isAddedDbContext) { dal.Delete(model, isAddedDbContext); }#endregion#region 3.0 改/// < summary> /// 编辑,约定model 是一个自定义的实体,没有追加到EF容器中的 /// < /summary> /// < param name="model"> < /param> public virtual void Edit(TEntity model, string[] propertyNames) { dal.Edit(model, propertyNames); }#endregion#region 4.0 查/// < summary> /// 带条件查询 /// < /summary> /// < param name="where"> < /param> /// < returns> < /returns> public virtual List< TEntity> QueryWhere(Expression< Func< TEntity, bool> > where) { return dal.QueryWhere(where); }#endregion#region 5.0 统一保存/// < summary> /// 统一将EF容器对象中的所有代理类生成相应的sql语句发给db服务器执行 /// < /summary> /// < returns> < /returns> public virtual int SaveChanges() { return dal.SaveChanges(); }#endregion}

View Codesystem文件中User_BLL.cs
ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

文章图片
ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

文章图片
public class User_BLL : BaseBLL< User> , User_IBLL { User_IDAL dalSer; public User_BLL(User_IDAL dalSer) { base.dal = dalSer; this.dalSer = dalSer; } }

View Code 
  5】公共层all文件夹代码以及结构(圈起来的都是要引用的,前面有红线的则是在nuget中引用  注意引用mvc的版本必须和自己ui层mvc版本一致)
ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

文章图片

IOCDI.CS
ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

文章图片
ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

文章图片
using autoTS.IBLL.system; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Web.Mvc; namespace autoTS.Mapperx.System { publicclass IOCDI : Controller { protected User_IBLL UserSer; protected UserType_IBLL UserTypeSer; } }

View Code(本次重点)EntityExtMethod.cs中代码是为了实现automapper
ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

文章图片
ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

文章图片
using AutoMapper; using autoTS.Model.System; using autoTS.ModelView.SystemView; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace autoTS.Mapperx { public static class EntityExtMethod { #region UserView-User public static UserView EntityMap(this User model) { //利用AutoMapper 来将 User 的属性值动态拷贝到 UserView 类中对应的同名属性值中 // 开始转换 return Mapper.Map< User, UserView> (model); } public static UserEntityMap(this UserView model) { //利用AutoMapper 来将 UserView 的属性值动态拷贝到 User 类中对应的同名属性值中 // 开始转换 return Mapper.Map< UserView, User> (model); } #endregion #region UserTypeView-Type public static UserTypeView EntityMap(this UserType model) { //利用AutoMapper 来将 UserType 的属性值动态拷贝到 UserTypeView 类中对应的同名属性值中 // 开始转换 return Mapper.Map< UserType, UserTypeView> (model); } public static UserType EntityMap(this UserTypeView model) { //利用AutoMapper 来将 UserTypeView 的属性值动态拷贝到 UserType 类中对应的同名属性 // 开始转换 return Mapper.Map< UserTypeView, UserType> (model); } #endregion } }

View Code
ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

文章图片

6】最后来到ui层 
ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

文章图片
ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

文章图片
方框里面是引用部分。而前面带红线的则是需要到nuget中引用(注意第二个autofac.integration.MVC是在nuegt中引用autofac.MVC5得到)
首先在app_Start中添加AutoFacConfig.cs(关于这部分内容,之前一份博客已经讲过就不多重复)
ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

文章图片
ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

文章图片
using Autofac; using Autofac.Integration.Mvc; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Web; using System.Web.Mvc; namespace WebApplication1.App_Start { public class AutoFacConfig { /// < summary> /// 负责调用autofac框架实现业务逻辑层和数据仓储层程序集中的类型对象的创建 /// 负责创建MVC控制器类的对象(调用控制器中的有参构造函数),接管DefaultControllerFactory的工作 /// < /summary> public static void Register() { //实例化一个autofac的创建容器 var builder = new ContainerBuilder(); //告诉Autofac框架,将来要创建的控制器类存放在哪个程序集 (IOCtsX.UI) Assembly controllerAss = Assembly.Load("WebApplication1"); builder.RegisterControllers(controllerAss); //告诉autofac框架注册数据仓储层所在程序集中的所有类的对象实例 Assembly respAss = Assembly.Load("autoTS.DAL"); //创建respAss中的所有类的instance以此类的实现接口存储 builder.RegisterTypes(respAss.GetTypes()).AsImplementedInterfaces(); //告诉autofac框架注册业务逻辑层所在程序集中的所有类的对象实例 Assembly serpAss = Assembly.Load("autoTS.BLL"); //创建serAss中的所有类的instance以此类的实现接口存储 builder.RegisterTypes(serpAss.GetTypes()).AsImplementedInterfaces(); //创建一个Autofac的容器 var container = builder.Build(); //将MVC的控制器对象实例 交由autofac来创建 DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); } } }

View Code然后再app_Start中添加AutoMapperConfig.cs。这部分一看就是为了实现automapper内容
ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

文章图片
ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

文章图片
using AutoMapper; using autoTS.Model.System; using autoTS.ModelView.SystemView; using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace WebApplication1.App_Start { public class AutoMapperConfig { public static void Initializex() { //Entity与DTO的映射 初始化映射的方向 (注册)写在这里是因为只需要注册一次, //放在C:\\Users\\Fates\\source\\repos\\automapperTS\\autoTS.Mapperx\\EntityExtMethod.cs 中因为每次使用都会注册从而报错(只需要注册一次) Mapper.Initialize(x => { x.CreateMap< User, UserView> (); //创建User映射到UserView x.CreateMap< UserView, UserType> (); //反之 x.CreateMap< UserType, UserTypeView> (); //创建UserType映射到UserTypeView x.CreateMap< UserTypeView, UserType> (); //反之 }); } } }

View Code注意自己引用的automapper,高版本和低版本的写法有些不同,如图
ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

文章图片

 
  如果不知道自己引用的是低版本还是高版本的话,就写Mapper.CreateMap< user, userView> (); 看是否报错,如果报错则是高版本的automapper,使用左上图写法,否者用右上图写法。
写完这些文件之后去Global.asax中进行注册
ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

文章图片

最后,我们来到控制器,写一个demo
ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

文章图片

最后来数据库看看结构
ioc初步理解 简单实用autofac搭建mvc三层+automapper=》ioc(codeFirst)

文章图片

 
 
  【总结】由于博主技术渣渣,所以文章内容不是太深入。只是简单介绍了如何简单的使用automapper,日后待到这一块深入了解之后,必将更新。此文章适合需要入门automapper的小白,跟着文章一步一步走必将写出一个可运行的demo。因为项目的所有代码和引用文件都已经做了详细的说明。如果懒人党的话,稍后会更新demo下载地址。同时也希望各位大牛的的意见与指点。
 

    推荐阅读