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

1】首先搭好框架

 1.1】搭建ui层

  1.2】建立其余内库文件

整个项目基本部分搭建完毕以后以下sql

2】使用nuget引用文件

先在每个项目中引入ef数据库

而后再UI层引入如下两个文件autofac和Autofac.Mvc5api

 

 

3】由于本demo实用codefirst,因此先去model层完善

  3.1】建立几个model 

   建立一个  User.cs。里面放几个属性 id、name、pwd。数组

  3.2】建立DBContext.cs这个文件的做用是自动生成数据库 内容以下

 

  3.3】建立DbModelContextFactory.cs。此处做用是:获取当前EF上下文的惟一实例;  内容以下

4】建立DAL层内容【须要使用nuget引入ef文件  和model文件。dal层还须要引入idal】

  4.1】首先完善IDAL(接口)内容

    4.1.1】首先完成基础部分,建立IBaseDAL.cs 在里面添加增删改查这四个基本操做(注意IDAL中全是接口不是类,因此新建的时候注意吧class改为interface)代码以下
 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 Code

 

    4.1.2】根据本身在model中建立的模型,在此处也一一对应的建立其dal层接口。所在这里建立一个IUser_DAL.cs  内容以下:

由于所建立的model只有一个user,因此IDAL层到此结束。服务器

  4.2】接下来建立DAL部份内容

   4.2.1】首先建立DbContextFactory.cs  =>   //获取当前EF上下文的惟一实例 代码以下

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

 

    4.2.2】首先建立BaseDAL.cs 在里面写入具体的增删该查操做,代码以下:
public class BaseDAL<TEntity> : IBaseDAL<TEntity> where TEntity : class
    {//1.0  实例化EF上下文 
        DbContext db = DbContextFactory.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 Code
   4.2.3】建立 User_DAL.cs文件,内容以下

 

5】建立BLL的内容【须要使用nuget引入ef文件   和导入model层。dal层文件,bll层还须要引入ibll层】

  5.1】先建立IBLL(接口)层的内容

    5.1.1】建立IBaseBLL.cs。代码以下
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 Code
   5.1.2】根据model层的模型建立ibll层接口。所在这里建立一个IUser_BLL.cs  内容以下:

 

  5.2】完善BLL层内容

    5.2.1】建立BaseBLL.cs,代码以下
  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 Code
   5.2.2】根据model层的模型建立bll层文件。所在这里建立一个User_BLL.cs  代码以下:
   public class User_BLL : BaseBLL<User>, IUser_BLL
    {
        IUser_DAL dalSer;
        public User_BLL(IUser_DAL dalSer)
        {
            base.dal = dalSer;
            this.dalSer = dalSer;
        }
    }
View Code

至此,基础部分创建完毕,接下来创建ui层内容mvc

6】创建UI层内容【须要引入bll文件和dal文件  也就是6.1中图中的两个文件,不然autofac报错,找到不到文件】

  6.1】首先在App_Start文件夹下建AutoFacConfig.cs文件

 

代码:框架

    public class AutoFacConfig
    { /// <summary>
      /// 负责调用autofac框架实现业务逻辑层和数据仓储层程序集中的类型对象的建立
      /// 负责建立MVC控制器类的对象(调用控制器中的有参构造函数),接管DefaultControllerFactory的工做
      /// </summary>
        public static void Register()
        {
            //实例化一个autofac的建立容器
            var builder = new ContainerBuilder();
            //告诉Autofac框架,未来要建立的控制器类存放在哪一个程序集 (IOCtsX.UI)
            Assembly controllerAss = Assembly.Load("IOCtsX.UI");
            builder.RegisterControllers(controllerAss);

            //告诉autofac框架注册数据仓储层所在程序集中的全部类的对象实例
            Assembly respAss = Assembly.Load("IOCtsX.IDAL");
            //建立respAss中的全部类的instance以此类的实现接口存储
            builder.RegisterTypes(respAss.GetTypes()).AsImplementedInterfaces();

            //告诉autofac框架注册业务逻辑层所在程序集中的全部类的对象实例
            Assembly serpAss = Assembly.Load("IOCtsX.BLL");
            //建立serAss中的全部类的instance以此类的实现接口存储
            builder.RegisterTypes(serpAss.GetTypes()).AsImplementedInterfaces();

            //建立一个Autofac的容器
            var container = builder.Build();
            //将MVC的控制器对象实例 交由autofac来建立
            DependencyResolver.SetResolver(new AutofacDependencyResolver(container));


        }
    }
View Code

  6.2】而后再Global.asax中进行配置 以下:

  6.3】建立一个公共层,使用nuget引入mvc和ef。添加文件IOCDI.cs 根据建立mode层中模型的数量写入内容:(写公共层主要考虑项目的扩展性,若是本项目中须要些api或者其余ui层时候,避免代码重复)【须要用nuget引入mvc、ef 和ibll层(注意此处mvc版本必须和ui层中mvc版本相同)】

 

7】最后建立一个控制器添加数据看看,

 7.1】先配置Web.config

 

 7.2】建立一个测试控制器(因为是codefirs因此不须要先建立数据库)

最后查看数据库ide

 

 

【最后附上关于autofac的几点疑惑】函数

1由于在ui层的App_Start下的AutoFacConfig.cs须要,因此ui层必须引用bll层和dal层,这和三层的理念有些差别。由于三层中ui层并不须要引入dal层。测试

【结尾说明,关于了解autofac花掉的时间说长也长说短也短。本来觉得在博客园、csdn上面找一找就能立刻获得一个能够运行的demo,可是不少博主都是按照本身的理解去写,在博文中或多或少会掉一些内容,这些内容对于博主和一些大牛来讲是能够忽略不计的,所以博文只须要核心代码就能够,可是对于我这种萌新来讲简直是灾难级别的,由于跟着博主敲打代码过程当中时长由于缺点什么而没法运行,本身也不知道错误在哪。所以不得不敲到一半立马换下一个。致使效率低下。因此在写这个博文的过程当中。我尽可能将每个细节所有罗列出来,以避免像我这样的小白看不懂。照着这个流程讲代码敲出来而且运行时没什么大问题的。由于我每敲完一处就写一点。最后将代码运行完毕,才敢上传。若是各位看官以为有什么问题能够在下方留言】

【若是须要代码能够去此下载,固然懒人也须要一点付出(csdn 3积分)。博主但愿你们尽可能多动手,多理解。不要像我以前同样只须要demo从不看文章致使后来吃了许多亏】

相关文章
相关标签/搜索