zoukankan      html  css  js  c++  java
  • .Net Core建站(3):搭建三层架构

    啊,终于到写三层架构的时候了,老实说,我都不知道自己这个算不算三层架构,姑且就当它是吧,具体属于哪一个体系,希望有大佬指点一下(^o^)/

    不晓得有人注意到没有,我写了三篇博客,然后就改了三次标题ヽ( ̄▽ ̄)ノ,

    从最开始的Core建数据库,到Core数据库操作,再到现在的Core建站,也算是下决心写个系列啊,,感觉要更好久的样子,,

    好吧,不要在意那些细节,文中可能会有一些我不知道的坑,毕竟自己也是一边自学一边写,不过保证功能还是能用的,发现有坑记得说,,我改,,(〃'▽'〃)

    // ===================emmm,我是分割线===================

     强烈推荐阅读:设计模式六大原则 讲的相当浅显易懂,,

    首先上一个截图,看看现在的项目结构,今天的主角是DataBase文件里面的那一堆项目啊,BLL,DAL和Interface,,Models是生成数据库时使用的,所以今天用不上,,

    按我的理解,先说说正常的三层架构吧,

    UI:界面层,这个层最简单,只是给BLL传递数据,然后,将BLL返回的数据进行一些处理,方便展示,

    BLL:业务逻辑层,接收UI层给的数据,写一些业务逻辑,第一步干啥,第二步干啥,什么什么的,然后把界面需要的数据返回出去,感觉更像是一个API

    DAL:数据访问层,BLL的业务逻辑处理时,总要涉及到数据库的操作,这时候就要用到DAL层了,,

    还有一个Model层,用来传递数据的,,不在三层范畴,,,

    不知道大家是怎么使用三层的,给大家展示一下以前学校教我们怎么用的三层架构啊,,

    分别对应三个类,UI层:HomeController,BLL层:DT_UserBLL,DAL层:DT_UserDAL

     1         // UI层
     2         public IActionResult Index(int userID)
     3         {
     4 
     5             // 根据条件,返回用户
     6             // 和BLL说,给你一堆条件,帮我把这些人找出来
     7             var userList = DT_UserBLL.GetUser(0,18);
     8 
     9             return View(userList);
    10 
    11         }
     1         /// <summary>
     2         /// BLL层,返回符合条件的用户
     3         /// </summary>
     4         /// <param name="sex">性别</param>
     5         /// <param name="age">年龄</param>
     6         /// <returns></returns>
     7         public List<DT_User> GetUser(int sex, int age)
     8         {
     9 
    10             #region 数据校验
    11 
    12             // 性别检测,0:女,1:男
    13             if (sex != 0 && sex != 1)
    14                 // 拒绝人妖
    15                 return null;
    16 
    17             // 年龄检测,[0,150]岁
    18             if (age < 0 || 150 < age)
    19                 // 拒绝妖怪
    20                 return null;
    21 
    22             #endregion
    23 
    24             // 和DAL说,数据我校验好了,不是恶搞,
    25             // 帮我查出来这些人,然后我交给UI就完事儿了,,
    26             return DT_UserDAL.GetUser(int sex, int age).ToList();
    27         }
     1         /// <summary>
     2         /// DAL层,返回符合条件的用户
     3         /// </summary>
     4         /// <param name="sex">性别</param>
     5         /// <param name="age">年龄</param>
     6         /// <returns></returns>
     7         public IQueryable<DT_User> GetUser(int sex, int age)
     8         {
     9             DbContext DB = new DbContext();
    10 
    11             return DB.Set<DT_User>().Where(c=>c.Sex==sex&&c.Age==age);
    12         }

    当时学着感觉蛮好的,挺新奇的一个编程思想,不过每一个数据表对应的DAL里面都得写一套增删查改,,简直是灾难,,[○・`Д´・ ○]

    出来实习之后,花了个把星期,把我们老大写的一个框架看明白了,就按图索骥地写了起来,嘿嘿

    其实和三层架构差不多的,只是把每个数据表对应的DAL里面的增删查改全部提出来,封装成了一个类,,

    然后对这个类进行继承,具体操作如下,,,

    首先啊,要大概了解一下依赖注入,,讲真,这个我也是一脸懵逼,所以就不复制百度百科了,,

    说说自己的理解吧,,,,emmm,此处可能有大量谬论,建议不要被我误导了,看看就好,别往心里去

    依赖注入这东西就好像一个全局的字典类型变量,,都是以键值对的方式存储的

    因为注册依赖注入服务的大部分语法是酱紫的,,,

    1 services.AddTransient(typeof(IDT_UserService), typeof(DT_UserService));

    而services这个变量的话,就像一个容器,用来存储这些键值对的,具体从哪来的,我也不知道,ヽ( ̄д ̄;)ノ

    而要使用的话,语法是酱紫的,,,

     1     public class HomeController : Controller
     2     {
     3         private IDT_UserService _UserService;
     4 
     5         public HomeController(IDT_UserService _UserService)
     6         {
     7             // 依赖注入得到实例
     8             this._UserService = _UserService;
     9         }
    10 
    11         public IActionResult Index()
    12         {
    13             ViewBag.list = _UserService.LoadEntites(c => true);
    14 
    15             return View();
    16         }
    17     }

    对的,完全不需要new,,其原理,,起码我不晓得,感觉甚是神奇,,

    先注册一个依赖注入的服务,然后要实例的时候,直接在构造函数里面把键的类型写上就好,,

    好了,灌毒就到此为止了,,还是继续上代码吧,,

    首先,得写一个数据库操作的底层类DalService又因为很多地方调用,所以,肯定是泛型,,

    然后为了解耦和方便注入,所以实现一个接口IDalService

    我暂时只写了添加和查询的方法,,其他的方法可以自由发挥,,不过记得先写接口,然后去实现接口中新加的方法,,不然无法使用的,,

    1     public interface IDalService<T> where T : class, new()
    2     {
    3         T AddEntity(T entity);
    4 
    5         IQueryable<T> LoadEntites(Expression<Func<T, bool>> where);
    6 
    7         int SaveChanges();
    8 
    9     }
    IDalService
     1     /// <summary>
     2     /// 数据访问层:DAL
     3     /// </summary>
     4     /// <typeparam name="T"></typeparam>
     5     public class DalService<T> : IDalService<T> where T : class, new()
     6     {
     7 
     8         private DbContext DbWrite;
     9         
    10         /// <summary>
    11         /// 获得数据库上下文
    12         /// </summary>
    13         /// <param name="dbContext">数据库上下文类,各自更改成自己的</param>
    14         public DalService(DBCodeFirst dbContext)
    15         {
    16             DbWrite = dbContext;
    17         }
    18 
    19         public T AddEntity(T entity)
    20         {
    21             DbWrite.Set<T>().Add(entity);
    22             return entity;
    23         }
    24 
    25         public IQueryable<T> LoadEntites(Expression<Func<T, bool>> where)
    26         {
    27             return DbWrite.Set<T>().Where(where);
    28         }
    29 
    30         public int SaveChanges()
    31         {
    32             return DbWrite.SaveChanges();
    33         }
    34 
    35     }
    DalService

    然后就没有DAL层啥事了,,咱们去看BLL层

    同样的写一个业务逻辑的父级类BllService,依旧是泛型,以及实现接口IBllService

    1     public interface IBllService<T>where T : class, new()
    2     {
    3         T AddEntity(T entity,bool IsSave);
    4 
    5         IQueryable<T> LoadEntites(Expression<Func<T, bool>> where);
    6 
    7         int SaveChanges();
    8     }
    IBllService
     1     /// <summary>
     2     /// 数据逻辑层:BLL
     3     /// </summary>
     4     public class BllService<T> : IBllService<T> where T : class, new()
     5     {
     6 
     7         /// <summary>
     8         /// 数据库服务
     9         /// </summary>
    10         protected IDalService<T> DBService;
    11 
    12         public BllService(IDalService<T> dalService)
    13         {
    14             this.DBService = dalService;
    15         }
    16 
    17         /// <summary>
    18         /// 保存实体
    19         /// </summary>
    20         /// <param name="entity"></param>
    21         /// <param name="IsSave"></param>
    22         /// <returns></returns>
    23         public T AddEntity(T entity, bool IsSave)
    24         {
    25             entity = DBService.AddEntity(entity);
    26             if (IsSave)
    27             {
    28                 if (SaveChanges() > 0)
    29                     return null;
    30             }
    31             return entity;
    32         }
    33 
    34         /// <summary>
    35         /// 查询数据
    36         /// </summary>
    37         /// <param name="where"></param>
    38         /// <returns></returns>
    39         public IQueryable<T> LoadEntites(Expression<Func<T, bool>> where)
    40         {
    41             return DBService.LoadEntites(where);
    42         }
    43 
    44         /// <summary>
    45         /// 保存数据库
    46         /// </summary>
    47         /// <returns></returns>
    48         public int SaveChanges()
    49         {
    50             return DBService.SaveChanges();
    51         }
    52     }
    BllService

    然后基本就完成了,,我们可以在BLL层创建一个DT_User的逻辑处理类,继承BllService,并实现接口IDT_UserService

    1     public interface IDT_UserService : IBllService<DT_User>
    2     {
    3         DT_User Insert();
    4 
    5         List<DT_User> GetList();
    6     }
    IDT_UserService
     1     public class DT_UserService : BllService<DT_User>, IDT_UserService
     2     { 
     3         /// <summary>
     4         /// 用于实例化父级,DBService变量
     5         /// </summary>
     6         /// <param name="dal"></param>
     7         public DT_UserService(IDalService<DT_User> dal) : base(dal)
     8         {
     9 
    10         }
    11 
    12         public DT_User Insert()
    13         {
    14             DT_User user = new DT_User
    15             {
    16                 Password = new Random().Next(0, 101) + "",
    17                 UserName = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
    18             };
    19             return AddEntity(user, true);
    20         }
    21 
    22         public List<DT_User> GetList()
    23         {
    24             return LoadEntites(c => true).ToList();
    25         }
    26 
    27     }
    DT_UserService

    最后使用的话,要把他们统统注册到服务里面,新建一个类DIBllRegister,用来注册这些和数据库相关的服务

     1     /// <summary>
     2     /// Bll层依赖注入
     3     /// </summary>
     4     public class DIBllRegister
     5     {
     6 
     7         public void DIRegister(IServiceCollection services)
     8         {
     9             // 用于实例化DalService对象,获取上下文对象
    10             services.AddTransient(typeof(IDalService<>), typeof(DalService<>));
    11 
    12             // 配置一个依赖注入映射关系 
    13             services.AddTransient(typeof(IDT_UserService), typeof(DT_UserService));
    14         }
    15     }
    DIBllRegister

    Startup的ConfigureServices方法中添加两行代码

     1         /// <summary>
     2         /// 运行时调用此方法。使用此方法向容器添加服务。
     3         /// </summary>
     4         /// <param name="services"></param>
     5         public void ConfigureServices(IServiceCollection services)
     6         {
     7             services.AddOptions();
     8 
     9             // 数据库连接字符串
    10             var conStr = Config.GetVal<string>(ConfigKey.ConStr);
    11             services.AddDbContext<DBCodeFirst>(options => options.UseSqlServer(conStr));
    12 
    13             DIBllRegister bllRegister = new DIBllRegister();
    14             bllRegister.DIRegister(services);
    15             
    16             services.AddMvc();
    17         }

    然后我们就可以愉快的使用三层架构来写项目了,,ヽ(≧∀≦)ノ

    示例以及项目结构如下:

    运行结果:

     注意事项:

    1. BLL层的类一定要继承BllService,并实现它对应的接口,参考上文DT_UserService类的格式
    2. BLL,DAL任何类要添加方法时,一定要在对应的接口中有个同样的入口,不然无法调用
    3. BLL层添加类时,记得在DIBllRegisterDIRegister中添加一行注册服务的代码,不然无法调用
    4. 差不多就这些,我想起来了再加,,,

    其实这个是我从Framework搬过来的,心塞得简直不要不要的,,,填坑日记就不写出来了,,

    具体的搭建思想也不太好用文字表述,大佬不要吐槽,萌新可以照着步骤去建一个小项目调试着看,,

    个人感觉还是比较好懂的,,毕竟,基本上全是核心代码还带注释,加一个使用样例,

    然后就是下集预告了,云服务器的FTP发布和数据库连接吧,,毕竟云服务器到手辣么久了,也该拉出来溜溜,,(❁´◡`❁)*✲゚*

    最后,,有坑记得说,,,,

  • 相关阅读:
    centos 7 安装ntp服务器
    centos 7编译安装nodejs 6.1
    修改IKAnalyzer配置
    Elasticsearch5.5.0安装head插件
    搭建ELASTICSEARCH实现中文分词搜索功能
    0426HTML基础:标签
    事件事件流
    纯css设置各行变色
    dom操作之元素的增删复制
    dom操作
  • 原文地址:https://www.cnblogs.com/Onlooker/p/8231522.html
Copyright © 2011-2022 走看看