[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 }
DataAccess

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 }
IBaseDAL
 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 }
IUserDAL

 

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 }
UserDAL
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#基础]使用抽象工厂实现三层 和反射的主要内容,如果未能解决你的问题,请参考以下文章

抽象工厂————三层架构

一抽象工厂模式&&简单工厂+反射改进抽象工厂

应用抽象工厂+反射实现通用数据源的设计

14抽象工厂获取数据访问层的实例,缓存的使用和反射的使用

反射+抽象工厂

反射+配置文件+抽象工厂