码迷,mamicode.com
首页 > Web开发 > 详细

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

时间:2018-11-14 16:43:09      阅读:273      评论:0      收藏:0      [点我收藏+]

标签:sum   row   业务逻辑层   png   pass   entity   处理   引入   closed   

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

技术分享图片

最后查看数据库

技术分享图片

 

 

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

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

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

标签:sum   row   业务逻辑层   png   pass   entity   处理   引入   closed   

原文地址:https://www.cnblogs.com/1439107348s/p/9957307.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!