三层架构之泛型抽象
关于泛型抽象工厂,最近自己写了一个项目,现在拿出来和大家分享,有助于我们学习。
项目截图如下:
XU.Model层中有一个抽象类BaseModel.cs是用户实体类,继承与BaseModel类,是用于类型安全考虑的,从而让 各实体类有一个统一的父类,在其他层使用的时候,可以使用里氏替换原则的考虑。
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace XU.Model 8 { 9 /// <summary> 10 /// 该抽象类为所有实体类的父类 11 /// 所有实体类继承该抽象类,为保持类型一致而设计的父类,也是出于安全性的考虑 12 /// </summary> 13 public abstract class BaseModel 14 { 15 16 } 17 }
1 1 using System; 2 2 using System.Collections.Generic; 3 3 using System.Linq; 4 4 using System.Text; 5 5 using System.Threading.Tasks; 6 6 7 7 namespace XU.Model.Student 8 8 { 9 9 /// <summary> 10 10 /// 实体类Student继承自BaseModel 11 11 /// 调用时就可以通过BaseModel model=new Student(); 12 12 /// </summary> 13 13 public class Student : BaseModel 14 14 { 15 15 public int Id { get; set; } 16 16 public string Name { get; set; } 17 17 public string SubjectName { get; set; } 18 18 public int Score { get; set; } 19 19 } 20 20 }
XU.FactoryDAL层是用于反射获取实例,其中只用一个类。
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading.Tasks;
6
7 namespace XU.FactoryDAL
8 {
9 public class DataAccess<T> where T : class
10 {
11 //获取配置路径
12 private static readonly string path = System.Configuration.ConfigurationManager.AppSettings["DAL"];
13 private DataAccess() { }
14 /// <summary>
15 /// 创建实例 反射创建实例
16 /// </summary>
17 /// <param name="Type"></param>
18 /// <returns></returns>
19 public static T CreateDAL(string Type)
20 {
21 string className = string.Format(path + ".{0}", Type);
22 try
23 {
24 return (T)System.Reflection.Assembly.Load(path).CreateInstance(className);
25 }
26 catch (Exception ex)
27 {
28
29 throw new Exception(ex.Message.ToString());
30 }
31 }
32 }
33 }
XU.IDAL层依赖与XU.Model,其中包含一个基类接口IBaseDal.cs,还有一个用于定义一些基类接口没有方法的接口IStudentDal.cs,继承接口IBaseDal<T>。
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace XU.IDAL 8 { 9 /// <summary> 10 /// 所有的dal基本都有增删改查等功能,提取到dal接口层 11 /// 所有实现该接口的类必须实现所有的未实现的成员 12 /// </summary> 13 /// <typeparam name="T"></typeparam> 14 public interface IBaseDal<T> where T:XU.Model.BaseModel,new() 15 { 16 int Add(T model); 17 int Delete(int Id); 18 int Update(T model); 19 T GetModel(int Id); 20 } 21 }
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace XU.IDAL 8 { 9 /// <summary> 10 /// 需有特殊的方法的 可定义子接口 11 /// 如:登录 判断用户名是否存在 12 /// </summary> 13 public interface IStudentDal:IBaseDal<Model.Student.Student> 14 { 15 16 /// <summary> 17 /// 判断用户名是否存在 18 /// </summary> 19 /// <param name="userName"></param> 20 /// <returns></returns> 21 // bool Exists(string userName); 22 /// <summary> 23 /// 登录 24 /// </summary> 25 /// <param name="name"></param> 26 /// <param name="pwd"></param> 27 /// <returns></returns> 28 // Model.UserModel Login(string name, string pwd); 29 30 //显示方法可写到IBaseDal.cs 不属于特殊方法 31 List<Model.Student.Student> GetList(); 32 33 } 34 }
实现XU.IDAL中接口有2个类库,一个是MSSQL类库,一个是MYSQL类库,这2两个类库都依赖于XU.Model和XU.IDAL,下面是实现方法。
XU.MSSQLDAL的实现方法如下:
1 using System; 2 using System.Collections.Generic; 3 using System.Data; 4 using System.Linq; 5 using System.Text; 6 using System.Threading.Tasks; 7 using XU.Model.Student; 8 9 namespace XU.MSSQDAL 10 { 11 public class StudentDal : IDAL.IStudentDal 12 { 13 /// <summary> 14 /// 添加 15 /// </summary> 16 /// <param name="model"></param> 17 /// <returns></returns> 18 public int Add(Student model) 19 { 20 string sql = string.Format("insert into Student values('{0}','{1}',{2})", model.Name, model.SubjectName, model.Score); 21 return DBHelper.ExecuteNonQuery(sql); 22 } 23 /// <summary> 24 /// 删除 25 /// </summary> 26 /// <param name="Id"></param> 27 /// <returns></returns> 28 public int Delete(int Id) 29 { 30 string sql = "Delete Student where Id=" + Id; 31 return DBHelper.ExecuteNonQuery(sql); 32 } 33 /// <summary> 34 /// 查询显示 35 /// </summary> 36 /// <returns></returns> 37 public List<Student> GetList() 38 { 39 string sql = "select * from Student"; 40 return DBHelper.GetList<Student>(sql); 41 } 42 /// <summary> 43 /// 反填 44 /// </summary> 45 /// <param name="Id"></param> 46 /// <returns></returns> 47 public Student GetModel(int Id) 48 { 49 string sql = "select * from Student where Id=" + Id; 50 return DBHelper.GetList<Student>(sql).FirstOrDefault(); 51 } 52 /// <summary> 53 /// 修改 54 /// </summary> 55 /// <param name="model"></param> 56 /// <returns></returns> 57 public int Update(Student model) 58 { 59 string sql = string.Format("Update Student Set Name='{0}',SubjectName='{1}',Score={2} where Id={3}",model.Name,model.SubjectName,model.Score,model.Id); 60 return DBHelper.ExecuteNonQuery(sql); 61 } 62 } 63 }
XU.MYSQLDAL的实现方法如下:
1 using System; 2 using System.Collections.Generic; 3 using System.Data; 4 using System.Linq; 5 using System.Text; 6 using System.Threading.Tasks; 7 using XU.Model.Student; 8 9 namespace XU.MYSQLDAL 10 { 11 public class StudentDal : IDAL.IStudentDal 12 { 13 /// <summary> 14 /// 添加 15 /// </summary> 16 /// <param name="model"></param> 17 /// <returns></returns> 18 public int Add(Student model) 19 { 20 string sql = string.Format("insert into Student(Name,SubjectName,Score) values('{0}','{1}',{2})", model.Name, model.SubjectName, model.Score); 21 return MySqlDBHelper.ExecuteNonQuery(sql); 22 } 23 /// <summary> 24 /// 删除 25 /// </summary> 26 /// <param name="Id"></param> 27 /// <returns></returns> 28 public int Delete(int Id) 29 { 30 string sql = "Delete from Student where Id=" + Id; 31 return MySqlDBHelper.ExecuteNonQuery(sql); 32 } 33 /// <summary> 34 /// 查询显示 35 /// </summary> 36 /// <returns></returns> 37 public List<Student> GetList() 38 { 39 string sql = "select * from Student"; 40 return MySqlDBHelper.GetList<Student>(sql); 41 } 42 /// <summary> 43 /// 反填 44 /// </summary> 45 /// <param name="Id"></param> 46 /// <returns></returns> 47 public Student GetModel(int Id) 48 { 49 string sql = "select * from Student where Id=" + Id; 50 return MySqlDBHelper.GetList<Student>(sql).FirstOrDefault(); 51 } 52 53 public int Update(Student model) 54 { 55 string sql = string.Format("update Student set Name='{0}',SubjectName='{1}',Score='{2}' where Id ={3}", model.Name, model.SubjectName, model.Score, model.Id); 56 return MySqlDBHelper.ExecuteNonQuery(sql); 57 } 58 59 60 61 } 62 }
XU.BLL业务逻辑层中包含了一个用于继承的基类BaseBLL<T>和用户业务逻辑StudentBll类,这层依赖XU.IDAL,XU.Model,XU.FactoryDAL库
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace XU.BLL 8 { 9 public class BaseBLL<T> where T:XU.Model.BaseModel,new() 10 { 11 protected XU.IDAL.IBaseDal<T> Dal; 12 public BaseBLL(string type) 13 { 14 //通过工厂得到dal 15 Dal = XU.FactoryDAL.DataAccess<XU.IDAL.IBaseDal<T>>.CreateDAL(type); 16 } 17 /// <summary> 18 /// 增加 19 /// </summary> 20 /// <param name="model"></param> 21 /// <returns></returns> 22 public virtual int Add(T model) 23 { 24 return Dal.Add(model); 25 } 26 /// <summary> 27 /// 删除 28 /// </summary> 29 /// <param name="Id"></param> 30 /// <returns></returns> 31 public virtual int Delete(int Id) 32 { 33 return Dal.Delete(Id); 34 } 35 /// <summary> 36 /// 修改 37 /// </summary> 38 /// <param name="model"></param> 39 /// <returns></returns> 40 public virtual int Update(T model) 41 { 42 return Dal.Update(model); 43 } 44 /// <summary> 45 /// 反填 46 /// </summary> 47 /// <param name="Id"></param> 48 /// <returns></returns> 49 public virtual T GetModel(int Id) 50 { 51 return Dal.GetModel(Id); 52 } 53 } 54 }
1 using System; 2 using System.Collections.Generic; 3 using System.Data; 4 using System.Linq; 5 using System.Text; 6 using System.Threading.Tasks; 7 using XU.Model.Student; 8 9 namespace XU.BLL 10 { 11 public class StudentBll:BaseBLL<XU.Model.Student.Student> 12 { 13 private const string _Type = "StudentDal"; 14 private XU.IDAL.IStudentDal _Dal; 15 public StudentBll() : base(_Type) 16 { 17 _Dal = base.Dal as XU.IDAL.IStudentDal; 18 if(_Dal == null) 19 { 20 throw new NullReferenceException(_Type); 21 } 22 } 23 /// <summary> 24 /// 查询方法 25 /// </summary> 26 /// <returns></returns> 27 public List<Student> GetList() 28 { 29 return _Dal.GetList(); 30 } 31 } 32 }
XU.ConsoleDemo是一个MVC项目,用这个讲解抽象工厂更简单和直观,项目中只包含了基础的增删改查操作
控制器如下:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.Mvc; 6 using XU.BLL; 7 using XU.Model.Student; 8 using Newtonsoft.Json; 9 using System.Data; 10 11 namespace XU.ConsoleDemo.Controllers 12 { 13 public class SchoolController : Controller 14 { 15 StudentBll bll = new StudentBll(); 16 /// <summary> 17 /// 添加显示方法 18 /// </summary> 19 /// <returns></returns> 20 [HttpGet] 21 public ActionResult Create() 22 { 23 return View(); 24 } 25 /// <summary> 26 /// 添加执行方法 27 /// </summary> 28 /// <param name="stu"></param> 29 /// <returns></returns> 30 [HttpPost] 31 public ActionResult Create(Student stu) 32 { 33 int n = bll.Add(stu); 34 if (n > 0) 35 { 36 return Content("添加成功"); 37 } 38 else 39 { 40 return Content("添加失败"); 41 } 42 } 43 /// <summary> 44 /// 学生显示 45 /// </summary> 46 /// <returns></returns> 47 public ActionResult Index() 48 { 49 var list = bll.GetList(); 50 var json = JsonConvert.SerializeObject(list); 51 List<Student> show = JsonConvert.DeserializeObject<List<Student>>(json); 52 return View(show); 53 } 54 public ActionResult Delete(int Id) 55 { 56 int n = bll.Delete(Id); 57 if (n > 0) 58 { 59 return Content("删除成功"); 60 } 61 else 62 { 63 return Content("删除失败"); 64 } 65 } 66 /// <summary> 67 /// 修改反填 68 /// </summary> 69 /// <param name="Id"></param> 70 /// <returns></returns> 71 [HttpGet] 72 public ActionResult Edit(int Id) 73 { 74 Student stu = bll.GetModel(Id); 75 76 return View(stu); 77 } 78 /// <summary> 79 /// 修改执行方法 80 /// </summary> 81 /// <param name="stu"></param> 82 /// <returns></returns> 83 [HttpPost] 84 public ActionResult Edit(Student stu) 85 { 86 int n = bll.Update(stu); 87 if (n > 0) 88 { 89 return Content("修改成功"); 90 } 91 else 92 { 93 return Content("修改失败"); 94 } 95 } 96 97 } 98 }
web.config程序集名称
1 <?xml version="1.0" encoding="utf-8" ?> 2 <configuration> 3 <appSettings> 4 <!--DAL路径--> 5 <add key="DAL" value="XU.MYSQLDAL"/> 6 <!-- 7 <add key="DAL" value="XU.MSSQDAL"/> 8 --> 9 </appSettings> 10 </configuration>
注意:XU.ConsoleDemo是不会直接引用XU.MSSQLDAL和XU.MYSQLDAL的,但是XU.ConsoleDemo中的Debug目录下要把编译好的XU.MSSQLDAL.dll和XU.MYSQLDAL.dll放进去,如果是网站就要放入网站中的Bin文件夹下
源码下载: https://pan.baidu.com/s/1CsbkCQl2M8IQ7BEtVMLKng 提取码: 5w36