[c#基础]使用抽象工厂实现三层 和反射
Posted 狼牙者.net
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[c#基础]使用抽象工厂实现三层 和反射相关的知识,希望对你有一定的参考价值。
引言
昨天加了一天班,今天闲来无事,就在想如何将之前的三层和最近一直在学的设计模式给联系在一起,然后就动手弄了个下面的小demo。
项目结构
项目各个层实现
Wolfy.Model层中有一个抽象类BaseModel.cs,User.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 Wolfy.Model 8 { 9 /// <summary> 10 /// 该抽象类为所有实体类的父类, 11 /// 所有实体类继承该抽象类, 为保持类型一致而设计的父类,也是出于安全性的考虑 12 /// </summary> 13 public abstract class BaseModel 14 { 15 } 16 }
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace Wolfy.Model 8 { 9 /// <summary> 10 /// 实体类user继承自BaseModel 11 /// 调用时就可以通过BaseModel model=new UserModel(); 12 /// </summary> 13 public class UserModel : BaseModel 14 { 15 public int Id { get; set; } 16 public string UserName { set; get; } 17 public string Password { set; get; } 18 } 19 }
Wolfy.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 Wolfy.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 } 27 catch (Exception ex) 28 { 29 throw new Exception(ex.Message.ToString()); 30 } 31 } 32 } 33 }
Wolfy.IDAL层依赖与Wolfy.Model,其中包含一个基接口IBaseDAL.cs,还有一个用于定义一些基接口中没有方法的接口IUserDAL,继承基接口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 Wolfy.IDAL 8 { 9 /// <summary> 10 /// 所有的dal基本都有增删改查等功能,提取到dal接口层, 11 /// 所有实现该接口的类必须实现所有的未实现的成员 12 /// </summary> 13 /// <typeparam name="T"></typeparam> 14 public interface IBaseDAL<T> where T : Model.BaseModel, new() 15 { 16 bool Add(T model); 17 bool Detele(int ID); 18 bool 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 Wolfy.IDAL 8 { 9 /// <summary> 10 /// 需有特殊的方法的 可定义子接口 11 /// </summary> 12 public interface IUserDAL:IBaseDAL<Model.UserModel> 13 { 14 /// <summary> 15 /// 判断用户名是否存在 16 /// </summary> 17 /// <param name="userName"></param> 18 /// <returns></returns> 19 bool Exists(string userName); 20 /// <summary> 21 /// 登录 22 /// </summary> 23 /// <param name="name"></param> 24 /// <param name="pwd"></param> 25 /// <returns></returns> 26 Model.UserModel Login(string name, string pwd); 27 } 28 }
Wolfy.DAL层,处理数据库的操作。
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 using System.Data; 7 using System.Data.SqlClient; 8 namespace Wolfy.DAL 9 { 10 public class UserDAL : Wolfy.IDAL.IUserDAL 11 { 12 public bool Exists(string userName) 13 { 14 string sql = "select count(*) from Users where UserName=@UserName"; 15 SqlParameter[] sp = { 16 new SqlParameter("@UserName",userName) 17 }; 18 19 return (int)SqlHelper.ExecuteScalar(CommandType.Text, sql, sp) > 0; 20 } 21 22 public bool Add(Model.UserModel model) 23 { 24 string sql = "insert into Users values(@UserName,@UserPwd)"; 25 SqlParameter[] sp = { 26 new SqlParameter("@UserName",model.UserName), 27 new SqlParameter("@UserName",model.Password) 28 }; 29 return SqlHelper.ExecuteNonQuery(CommandType.Text, sql, sp) > 0; 30 } 31 32 public bool Detele(int ID) 33 { 34 string sql = "delete from Users where id=" + ID; 35 return SqlHelper.ExecuteNonQuery(CommandType.Text, sql) > 0; 36 } 37 38 public bool Update(Model.UserModel model) 39 { 40 string sql = string.Format("update Users set UserName={0},UserPwd={1} where id={2}", model.UserName, model.Password, model.Id); 41 return SqlHelper.ExecuteNonQuery(CommandType.Text, sql) > 0; 42 } 43 44 public Model.UserModel GetModel(int ID) 45 { 46 string sql = "select * from Users where id=" + ID; 47 DataTable dt = SqlHelper.ExecuteDataTable(sql); 48 if (dt != null && dt.Rows.Count > 0) 49 { 50 return new Model.UserModel() { UserName = dt.Rows[0]["UserName"].ToString(), Password = dt.Rows[0]["UserPwd"].ToString() }; 51 } 52 else 53 { 54 return null; 55 } 56 } 57 58 59 public Model.UserModel Login(string name, string pwd) 60 { 61 Model.UserModel model = null; 62 string sql = "select * from Users where UserName=@UserName and UserPwd=@UserPwd"; 63 SqlParameter[] sp = { 64 new SqlParameter("@UserName",name), 65 new SqlParameter("@UserPwd",pwd) 66 }; 67 SqlDataReader reader = SqlHelper.ExecuteReader(CommandType.Text, sql, sp); 68 if (reader != null && !reader.IsClosed && reader.HasRows) 69 { 70 model = new Model.UserModel(); 71 while (reader.Read()) 72 { 73 model.Id = Convert.ToInt32(reader[0]); 74 model.UserName = reader[1].ToString(); 75 model.Password = reader[2].ToString(); 76 } 77 } 78 reader.Dispose(); 79 return model; 80 } 81 } 82 }
1 using System; 2 using System.Data; 3 using System.Xml; 4 using System.Data.SqlClient; 5 using System.Collections; 6 using System.Configuration; 7 using System.IO; 8 using System.Web; 9 10 11 namespace Wolfy.DAL 12 { 13 /// <summary> 14 /// 数据库的通用访问代码 15 /// 此类为抽象类,不允许实例化,在应用时直接调用即可 16 /// </summary> 17 public abstract class SqlHelper 18 { 19 //获取数据库连接字符串,其属于静态变量且只读,项目中所有文档可以直接使用,但不能修改 20 public static readonly string connectionString = ConfigurationManager.ConnectionStrings["SqlConnect"].ConnectionString; 21 22 23 // 哈希表用来存储缓存的参数信息,哈希表可以存储任意类型的参数。 24 private static Hashtable parmCache = Hashtable.Synchronized(new Hashtable()); 25 26 /// <summary> 27 ///执行一个不需要返回值的SqlCommand命令,通过指定专用的连接字符串。 28 /// 使用参数数组形式提供参数列表 29 /// </summary> 30 /// <remarks> 31 /// 使用示例: 32 /// int result = ExecuteNonQuery(connString, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24)); 33 /// </remarks> 34 /// <param name="connectionString">一个有效的数据库连接字符串</param> 35 /// <param name="commandType">SqlCommand命令类型 (存储过程, T-SQL语句, 等等。)</param> 36 /// <param name="commandText">存储过程的名字或者 T-SQL 语句</param> 37 /// <param name="commandParameters">以数组形式提供SqlCommand命令中用到的参数列表</param> 38 /// <returns>返回一个数值表示此SqlCommand命令执行后影响的行数</returns> 39 public static int ExecuteNonQuery(CommandType cmdType, string cmdText, params SqlParameter[] commandParameters) 40 { 41 SqlCommand cmd = new SqlCommand(); 42 using (SqlConnection conn = new SqlConnection(connectionString)) 43 { 44 //通过PrePareCommand方法将参数逐个加入到SqlCommand的参数集合中 45 PrepareCommand(cmd, conn, null, cmdType, cmdText, commandParameters); 46 int val = cmd.ExecuteNonQuery(); 47 //清空SqlCommand中的参数列表 48 cmd.Parameters.Clear(); 49 return val; 50 } 51 } 52 53 /// <summary> 54 ///执行一条不返回结果的SqlCommand,通过一个已经存在的数据库连接 55 /// 使用参数数组提供参数 56 /// </summary> 57 /// <remarks> 58 /// 使用示例: 59 /// int result = ExecuteNonQuery(conn, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24)); 60 /// </remarks> 61 /// <param name="conn">一个现有的数据库连接</param> 62 /// <param name="commandType">SqlCommand命令类型 (存储过程, T-SQL语句, 等等。)</param> 63 /// <param name="commandText">存储过程的名字或者 T-SQL 语句</param> 64 /// <param name="commandParameters">以数组形式提供SqlCommand命令中用到的参数列表</param> 65 /// <returns>返回一个数值表示此SqlCommand命令执行后影响的行数</returns> 66 public static int ExecuteNonQuery(SqlConnection connection, CommandType cmdType, string cmdText, params SqlParameter[] commandParameters) 67 { 68 SqlCommand cmd = new SqlCommand(); 69 PrepareCommand(cmd, connection, null, cmdType, cmdText, commandParameters); 70 int val = cmd.ExecuteNonQuery(); 71 cmd.Parameters.Clear(); 72 return val; 73 } 74 75 /// <summary> 76 /// 执行一条不返回结果的SqlCommand,通过一个已经存在的数据库事物处理 77 /// 使用参数数组提供参数 78 /// </summary> 79 /// <remarks> 80 /// 使用示例: 81 /// int result = ExecuteNonQuery(trans, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24)); 82 /// </remarks> 83 /// <param name="trans">一个存在的 sql 事物处理</param> 84 /// <param name="commandType">SqlCommand命令类型 (存储过程, T-SQL语句, 等等。)</param> 85 /// <param name="commandText">存储过程的名字或者 T-SQL 语句</param> 86 /// <param name="commandParameters">以数组形式提供SqlCommand命令中用到的参数列表</param> 87 /// <returns>返回一个数值表示此SqlCommand命令执行后影响的行数</returns> 88 public static int ExecuteNonQuery(SqlTransaction trans, CommandType cmdType, string cmdText, params SqlParameter[] commandParameters) 89 { 90 SqlCommand cmd = new SqlCommand(); 91 PrepareCommand(cmd, trans.Connection, trans, cmdType, cmdText, commandParameters); 92 int val = cmd.ExecuteNonQuery(); 93 cmd.Parameters.Clear(); 94 return val; 95 } 96 97 /// <summary> 98 /// 执行一条返回结果集的SqlCommand命令,通过专用的连接字符串。 99 /// 使用参数数组提供参数 100 /// </summary> 101 /// <remarks> 102 /// 使用示例: 103 /// SqlDataReader r = ExecuteReader(connString, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24)); 104 /// </remarks> 105 /// <param name="connectionString">一个有效的数据库连接字符串</param> 106 /// <param name="commandType">SqlCommand命令类型 (存储过程, T-SQL语句, 等等。)</param> 107 /// <param name="commandText">存储过程的名字或者 T-SQL 语句</param> 108 /// <param name="commandParameters">以数组形式提供SqlCommand命令中用到的参数列表</param> 109 /// <returns>返回一个包含结果的SqlDataReader</returns> 110 public static SqlDataReader ExecuteReader(CommandType cmdType, string cmdText, params SqlParameter[] commandParameters) 111 { 112 SqlCommand cmd = new SqlCommand(); 113 SqlConnection conn = new SqlConnection(connectionString); 114 // 在这里使用try/catch处理是因为如果方法出现异常,则SqlDataReader就不存在, 115 //CommandBehavior.CloseConnection的语句就不会执行,触发的异常由catch捕获。 116 //关闭数据库连接,并通过throw再次引发捕捉到的异常。 117 try 118 { 119 PrepareCommand(cmd, conn, 以上是关于[c#基础]使用抽象工厂实现三层 和反射的主要内容,如果未能解决你的问题,请参考以下文章