使用C#建立我的三层结构之一
三层结构,是我们学习设计框架最早接触的项目搭建方式,我们通过一步一步来进化我们的项目结构。
一、首先建立一个控制台项目,如下:
一开始,为了不分散我们的注意力,我们把所有的类全部写在Program.cs文件里,这样很直观,一眼就能看到全部代码结构。
需求:在控制台展示学生的信息。
分析:先定义一个学生的实体类,然后定义一个逻辑类,再定义一个数据访问层类,最后在客户端调用逻辑类获取学生信息,逻辑类会调用数据访问层获取学生信息,数据访问层应该去访问数据库的,这里我们先用代码给出2条数据,以表示从数据库获取到的数据。
代码简单,就不一步一步创建了,自己看
using System; using System.Collections; using System.Collections.Generic; using System.Runtime.InteropServices.ComTypes; namespace MyThreeLayers1 { class Program { static void Main(string[] args) { //第四步,调用逻辑层 var studentBll = new StudentBll(); var students = studentBll.GetStudents(); foreach (var student in students) { Console.WriteLine(student); } Console.ReadKey(); } } //第一步、创建实体类 public class Student { public int Id { get; set; } public string Name { get; set; } public override string ToString() { return $"{nameof(Id)}: {Id}, {nameof(Name)}: {Name}"; } } //第二步、创建数据访问层DAL,获取数据库数据 public class StudentDal { //这里应该是从数据库返回数据 private readonly IList<Student> _students = new List<Student> { new Student {Id = 1, Name = "海风"}, new Student {Id = 2, Name = "青云"} }; //获取数据的方法 public IEnumerable<Student> GetStudents() { return _students; } } //第三步、定义逻辑层BLL,调用DAL层的方法 public class StudentBll { public IEnumerable<Student> GetStudents() { var studentDal = new StudentDal();//实例化底层,方可调用其方法 var students = studentDal.GetStudents(); return students; } } }
运行结果:
====================================================================================
开始进化:使用接口,使用依赖注入。
1 using System; 2 using System.Collections.Generic; 3 4 namespace MyThreeLayers2 5 { 6 class Program 7 { 8 static void Main(string[] args) 9 { 10 //第六步,调用逻辑层,通过逻辑层的构造函数注入数据访问层对象 11 IStudentBll studentBll = new StudentBll(new StudentDal()); 12 var students = studentBll.GetStudents(); 13 foreach (var student in students) 14 { 15 Console.WriteLine(student); 16 } 17 18 //----------与版本1相比,通过定义接口和使用构造函数注入实现了BLL和DAL层的解耦。实现了DAL层的切换,这个过程中没有修改StudentBll代码------ 19 20 studentBll = new StudentBll(new StudentDal2()); 21 students = studentBll.GetStudents(); 22 23 foreach (var student in students) 24 { 25 Console.WriteLine(student); 26 } 27 28 29 Console.ReadKey(); 30 } 31 } 32 33 //第一步,创建实体类 34 public class Student 35 { 36 public int Id { get; set; } 37 public string Name { get; set; } 38 public override string ToString() 39 { 40 return $"{nameof(Id)}: {Id}, {nameof(Name)}: {Name}"; 41 } 42 } 43 44 //第二步,定义数据访问层DAL接口 45 public interface IStudentDal 46 { 47 IEnumerable<Student> GetStudents(); 48 } 49 50 //第三步,实现数据访问层DAL接口 51 public class StudentDal : IStudentDal 52 { 53 //数据库获取数据,这里用内存数据库替代一下 54 private readonly IList<Student> _students = new List<Student> 55 { 56 new Student{Id = 3, Name = "飞虎"}, 57 new Student{Id = 4, Name = "飞雕"} 58 }; 59 60 public IEnumerable<Student> GetStudents() 61 { 62 return _students; 63 } 64 } 65 //重点! 66 public class StudentDal2 : IStudentDal 67 { 68 //数据库获取数据,这里用内存数据库替代一下 69 private readonly IList<Student> _students = new List<Student> 70 { 71 new Student{Id = 5, Name = "通过定义接口和使用构造函数注入实现了BLL和DAL层的解耦。实现了DAL层的切换,这个过程中没有修改StudentBll代码"}, 72 73 }; 74 75 public IEnumerable<Student> GetStudents() 76 { 77 return _students; 78 } 79 } 80 81 82 //第四步,定义逻辑层BLL接口 83 public interface IStudentBll 84 { 85 IEnumerable<Student> GetStudents(); 86 } 87 //第五步,实现逻辑层BLL接口 88 public class StudentBll : IStudentBll 89 { 90 private readonly IStudentDal _studentDal;//很重要 91 92 /** 93 * 通过构造函数传入一个 IStudentDal 这种方式称为“构造函数注入” 94 * 使用构造函数注入的方式,使得不依赖于特定的 IStudentDal 实现。 95 * 只要 IStudentDal 接口的定义不修改,该类就不需要修改,实现了DAL与BLL的解耦 96 */ 97 public StudentBll(IStudentDal studentDal) 98 { 99 _studentDal = studentDal; 100 } 101 102 public IEnumerable<Student> GetStudents() 103 { 104 var students = _studentDal.GetStudents(); 105 return students; 106 } 107 } 108 109 }
简要分析:
与版本1相比,通过定义接口和使用构造函数注入实现了BLL和DAL层的解耦。实现了DAL层的切换,这个过程中没有修改StudentBll代码
运行结果: