DBSession是一个数据库会话层(放在DALFactory类库中,创建DAL实例),在BLL层和DAL层之间,作用:解耦BLL层与DAL层的关系,BLL层通过调用接口来完成相关的数据操作,这里只有一个数据库访问技术就是用EF,如果除了EFDAL还有一个SQLDAL,有一天老板突然让你把EFDAL换成SQLDAL实现同样的功能,那怎么办?
最好的,最偷懒的方法就是我们把写好的SQLDAL和IDAL层的接口定义的方法一致,让SQLDAL里面的类同样实现IDAL里面的接口,这样就不用去改代码而是增加代码而已,原来的代码还能用,如果有一天老板又让你换回来,而你把原来的修改了,那不是还要再写一遍…… 很麻烦
但是写好了SQLDAL就会发现有个问题,比如IUserInfoDAL它有两个子类,一个用EF实现的UserInfoDAL(UserInfoEFDAL),另一个用SQL实现的UserInfoSQLDAL,在BLL层调用的时候是这样调用的IUserInfoDAL userInfoDAL=new UserInfoEFDAL();然后userInfoDAL.什么,如果要使用SQLDAL里面的UserInfoSQLDAL就要把这个代码换成IUserInfoDAL userInfoDAL=new UserInfoSQLDAL();一两个这样的调用没什么,改的代码不多,但是如果有几百个,几千个改起来也会累死,更何况万一还要用回EFDAL呢!!!所以我们定义一个DBSession类
1 using DAL; 2 using IDAL; 3 using Model; 4 using System; 5 using System.Collections.Generic; 6 using System.Data.Entity; 7 using System.Linq; 8 using System.Text; 9 using System.Threading.Tasks; 10 11 namespace DALFactory 12 { 13 /// <summary> 14 /// DBSession:工厂类(数据会话层),作用创建数据操作类实例,业务层通过DBSession调用相应的实例,使数据层与业务层解耦 15 /// </summary> 16 public class DBSession:IDBSession 17 { 18 private IUserInfoDAL UserInfoDAL; 19 20 public IUserInfoDAL userInfoDAL 21 { 22 get 23 { 24 if (UserInfoDAL == null) 25 { 26 UserInfoDAL = new UserInfoEFDAL(); 27 //UserInfoDAL = new UserInfoSQLDAL(); 28 } 29 return UserInfoDAL; 30 } 31 set { UserInfoDAL = value; } 32 } 33 private IStuAnsDAL StuAnsDAL; 34 public IStuAnsDAL stuAnsDAL 35 { 36 get 37 { 38 if (StuAnsDAL == null) 39 { 40 StuAnsDAL = new StuAnsEFDAL(); 41 //StuAnsDAL = new StuAnsSQLDAL(); 42 } 43 return StuAnsDAL; 44 } 45 set { StuAnsDAL = value; } 46 } 47 } 48 } 49
这个类里封装了IUserInfoDAL UserInfoDAL实例和其他实例,但是需要改用DAL实例的时候都是修改这个类里的IUserInfoDAL UserInfoDAL属性,重新new 一个UserInfoSQLDAL实例,还是要改代码,“Don't repeat youself”,DBSession类是用来创建实例的,所以可以使用DALFactory工厂来完成这个工作,创建一个AbstractFactory工厂类,
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 using System.Configuration; 7 using IDAL; 8 using System.Reflection; 9 10 namespace DALFactory 11 { 12 /// <summary> 13 /// 抽象工厂:创建不同类型的DAL实例,例如在SQL和Oracle之间切换 14 /// </summary> 15 public class AbstractFactory 16 { 17 //程序集路径 18 private static readonly string DALAssemblyPath = ConfigurationManager.AppSettings["DALAssemblyPath"]; 19 //命名空间 20 private static readonly string NameSpace = ConfigurationManager.AppSettings["NameSpace"]; 21 /// <summary> 22 /// 创建UserInfoDAL实例,返回IUserInfoDAL接口实例 23 /// </summary> 24 /// <returns></returns> 25 public static IUserInfoDAL CreateUserInfoDAL() 26 { 27 string fullClassName = NameSpace + ".UserInfoDAL";//构建类的全名称 28 return CreateInstence(fullClassName) as IUserInfoDAL; 29 } 30 /// <summary> 31 /// 创建StuAnsDAL实例,返回IStuAnsDAL接口实例 32 /// </summary> 33 /// <returns></returns> 34 public static IStuAnsDAL CreateStuAnsDAL() 35 { 36 string fullClassName = NameSpace + ".StuAnsDAL"; 37 return CreateInstence(fullClassName) as IStuAnsDAL; 38 } 39 /// <summary> 40 /// 创建实例,反射创建实例 41 /// </summary> 42 /// <param name="fullClassName">完整类名</param> 43 /// <returns></returns> 44 public static object CreateInstence(string fullClassName) 45 { 46 var assmbly = Assembly.Load(DALAssemblyPath);//加载程序集 47 return assmbly.CreateInstance(fullClassName); 48 } 49 } 50 }
AbstractFactory需要在Web.config文件中配置两个节点,让AbstractFactory类能读取程序集的路径反射生成UserInfoDAL实例
1 <appSettings> 2 <add key="webpages:Version" value="2.0.0.0" /> 3 <add key="webpages:Enabled" value="false" /> 4 <add key="PreserveLoginUrl" value="true" /> 5 <add key="ClientValidationEnabled" value="true" /> 6 <add key="UnobtrusiveJavaScriptEnabled" value="true" /> 7 <!--DAL实例配置节点--> 8 <add key="DALAssemblyPath" value="DAL"/> 9 <add key="NameSpace" value="DAL"/> 10 </appSettings>
把DBSession中的IUserInfoDAL userInfoDAL=AbstractFactory.CreateUserInfoDAL();
这样只要修改Web.config中的程序集名称和程序集的命名空间就可以通过AbstractFactory类反射生成相应的DAL实例(EFDAL或者SQLDAL中的UserInfoDAL)
DBSession类封装好了,再开放一个IDBSession接口给BLL层调用
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace IDAL 8 { 9 public interface IDBSession 10 { 11 IUserInfoDAL userInfoDAL { set; get; } 12 IStuAnsDAL stuAnsDAL { set; get; } 13 } 14 }
三层就基本好了,