热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

.NetCore建站(3):搭建三层架构

啊,终于到写三层架构的时候了,老实说,我都不知道自己这个算不算三层架构,姑且就当它是吧,具体属于哪一个体系,希望有大佬指点一下(^o^)/不晓得有人注意到没有,我写了三篇博客,然后就改了三次标题ヽ(

啊,终于到写三层架构的时候了,老实说,我都不知道自己这个算不算三层架构,姑且就当它是吧,具体属于哪一个体系,希望有大佬指点一下(^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         /// 
2 /// BLL层,返回符合条件的用户
3 ///

4 /// 性别
5 /// 年龄
6 ///
7 public List 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         /// 
2 /// DAL层,返回符合条件的用户
3 ///

4 /// 性别
5 /// 年龄
6 ///
7 public IQueryable GetUser(int sex, int age)
8 {
9 DbContext DB = new DbContext();
10
11 return DB.Set().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 where T : class, new()
2 {
3 T AddEntity(T entity);
4
5 IQueryable LoadEntites(Expressionbool>> where);
6
7 int SaveChanges();
8
9 }
IDalService
 1     /// 
2 /// 数据访问层:DAL
3 ///

4 ///
5 public class DalService : IDalService where T : class, new()
6 {
7
8 private DbContext DbWrite;
9
10 ///
11 /// 获得数据库上下文
12 ///

13 /// 数据库上下文类,各自更改成自己的
14 public DalService(DBCodeFirst dbContext)
15 {
16 DbWrite = dbContext;
17 }
18
19 public T AddEntity(T entity)
20 {
21 DbWrite.Set().Add(entity);
22 return entity;
23 }
24
25 public IQueryable LoadEntites(Expressionbool>> where)
26 {
27 return DbWrite.Set().Where(where);
28 }
29
30 public int SaveChanges()
31 {
32 return DbWrite.SaveChanges();
33 }
34
35 }
DalService

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

 

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

1     public interface IBllServicewhere T : class, new()
2 {
3 T AddEntity(T entity,bool IsSave);
4
5 IQueryable LoadEntites(Expressionbool>> where);
6
7 int SaveChanges();
8 }
IBllService
 1     /// 
2 /// 数据逻辑层:BLL
3 ///

4 public class BllService : IBllService where T : class, new()
5 {
6
7 ///
8 /// 数据库服务
9 ///

10 protected IDalService DBService;
11
12 public BllService(IDalService dalService)
13 {
14 this.DBService = dalService;
15 }
16
17 ///
18 /// 保存实体
19 ///

20 ///
21 ///
22 ///
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 ///
35 /// 查询数据
36 ///

37 ///
38 ///
39 public IQueryable LoadEntites(Expressionbool>> where)
40 {
41 return DBService.LoadEntites(where);
42 }
43
44 ///
45 /// 保存数据库
46 ///

47 ///
48 public int SaveChanges()
49 {
50 return DBService.SaveChanges();
51 }
52 }
BllService

 

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

1     public interface IDT_UserService : IBllService
2 {
3 DT_User Insert();
4
5 List GetList();
6 }
IDT_UserService
 1     public class DT_UserService : BllService, IDT_UserService
2 {
3 ///
4 /// 用于实例化父级,DBService变量
5 ///

6 ///
7 public DT_UserService(IDalService 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 GetList()
23 {
24 return LoadEntites(c => true).ToList();
25 }
26
27 }
DT_UserService

 

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

 1     /// 
2 /// Bll层依赖注入
3 ///

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         /// 
2 /// 运行时调用此方法。使用此方法向容器添加服务。
3 ///

4 ///
5 public void ConfigureServices(IServiceCollection services)
6 {
7 services.AddOptions();
8
9 // 数据库连接字符串
10 var cOnStr= Config.GetVal<string>(ConfigKey.ConStr);
11 services.AddDbContext(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发布和数据库连接吧,,毕竟云服务器到手辣么久了,也该拉出来溜溜,,(❁´◡`❁)*✲゚*

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

 


推荐阅读
  • 本章将深入探讨移动 UI 设计的核心原则,帮助开发者构建简洁、高效且用户友好的界面。通过学习设计规则和用户体验优化技巧,您将能够创建出既美观又实用的移动应用。 ... [详细]
  • 本文详细探讨了JDBC(Java数据库连接)的内部机制,重点分析其作为服务提供者接口(SPI)框架的应用。通过类图和代码示例,展示了JDBC如何注册驱动程序、建立数据库连接以及执行SQL查询的过程。 ... [详细]
  • 深入解析 Apache Shiro 安全框架架构
    本文详细介绍了 Apache Shiro,一个强大且灵活的开源安全框架。Shiro 专注于简化身份验证、授权、会话管理和加密等复杂的安全操作,使开发者能够更轻松地保护应用程序。其核心目标是提供易于使用和理解的API,同时确保高度的安全性和灵活性。 ... [详细]
  • Startup 类配置服务和应用的请求管道。Startup类ASP.NETCore应用使用 Startup 类,按照约定命名为 Startup。 Startup 类:可选择性地包括 ... [详细]
  • 本文详细介绍了macOS系统的核心组件,包括如何管理其安全特性——系统完整性保护(SIP),并探讨了不同版本的更新亮点。对于使用macOS系统的用户来说,了解这些信息有助于更好地管理和优化系统性能。 ... [详细]
  • VPX611是北京青翼科技推出的一款采用6U VPX架构的高性能数据存储板。该板卡搭载两片Xilinx Kintex-7系列FPGA作为主控单元,内置RAID控制器,支持多达8个mSATA盘,最大存储容量可达8TB,持续写入带宽高达3.2GB/s。 ... [详细]
  • 尽管使用TensorFlow和PyTorch等成熟框架可以显著降低实现递归神经网络(RNN)的门槛,但对于初学者来说,理解其底层原理至关重要。本文将引导您使用NumPy从头构建一个用于自然语言处理(NLP)的RNN模型。 ... [详细]
  • 本文详细介绍了如何在Ubuntu系统中下载适用于Intel处理器的64位版本,涵盖了不同Linux发行版对64位架构的不同命名方式,并提供了具体的下载链接和步骤。 ... [详细]
  • 5G至4G空闲态移动TAU流程解析
    本文详细解析了用户从5G网络移动到4G网络时,在空闲态下触发的跟踪区更新(TAU)流程。通过N26接口实现无缝迁移,确保用户体验不受影响。 ... [详细]
  • 并发编程:深入理解设计原理与优化
    本文探讨了并发编程中的关键设计原则,特别是Java内存模型(JMM)的happens-before规则及其对多线程编程的影响。文章详细介绍了DCL双重检查锁定模式的问题及解决方案,并总结了不同处理器和内存模型之间的关系,旨在为程序员提供更深入的理解和最佳实践。 ... [详细]
  • MySQL索引详解与优化
    本文深入探讨了MySQL中的索引机制,包括索引的基本概念、优势与劣势、分类及其实现原理,并详细介绍了索引的使用场景和优化技巧。通过具体示例,帮助读者更好地理解和应用索引以提升数据库性能。 ... [详细]
  • 本文探讨了MariaDB在当前数据库市场中的地位和挑战,分析其可能面临的困境,并提出了对未来发展的几点看法。 ... [详细]
  • 毕业设计:基于机器学习与深度学习的垃圾邮件(短信)分类算法实现
    本文详细介绍了如何使用机器学习和深度学习技术对垃圾邮件和短信进行分类。内容涵盖从数据集介绍、预处理、特征提取到模型训练与评估的完整流程,并提供了具体的代码示例和实验结果。 ... [详细]
  • 本文探讨了dbforms框架的核心设计理念及其背后的技术原理,详细分析了该框架如何通过其独特的设计模式来简化开发流程,并为开发者提供了优化使用方法的建议。 ... [详细]
  • 深入理解ASP.NET MVC中的_ViewStart.cshtml
    本文介绍了_ViewStart.cshtml文件在ASP.NET MVC 3.0及以上版本中的作用和使用方法。该文件位于Views目录下,主要用于统一配置视图布局和其他全局设置。 ... [详细]
author-avatar
强悍的梅子
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有