zoukankan      html  css  js  c++  java
  • ioc初步理解(一) 简单实用autofac搭建mvc三层+ioc(codeFirst)

    1】首先搭好框架

     1.1】搭建ui层

      1.2】创建其他内库文件

    整个项目基本部分搭建完毕之后如下

    2】使用nuget引用文件

    先在每一个项目中引入ef

    然后再UI层引入以下两个文件autofac和Autofac.Mvc5

    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层内容

    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.DAL");
                //创建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所以不需要先创建数据库)

    最后查看数据库

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

    1因为在ui层的App_Start下的AutoFacConfig.cs需要,所以ui层必须引用bll层和dal层,这和三层的理念有些差异。因为三层中ui层并不需要引入dal层。

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

    【如果需要代码可以去此下载,当然懒人也需要一点付出(csdn 3积分)。博主希望大家尽量多动手,多理解。不要像我之前一样只需要demo从不看文章导致后来吃了许多亏】

  • 相关阅读:
    10年后我又来看看我自己!
    KubernetesKuboard
    VSCode SSH 免密登录
    Windows Terminal 使用 PuTTY 连接 COM 串口
    PuTTY SSH 免密登录
    FastDDS 安装过程的坑🕳坑🕳坑🕳坑🕳坑🕳坑🕳
    Samba 安装、配置、共享 home 目录、创建用户、设置密码、映射盘符
    Win10 恢复快捷方式小箭头
    CSAPP 并发编程读书笔记
    修改 VSCode 终端配色
  • 原文地址:https://www.cnblogs.com/1439107348s/p/9957307.html
Copyright © 2011-2022 走看看