首页 > 代码库 > [c#基础]使用抽象工厂实现三层 和反射

[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, null, cmdType, cmdText, commandParameters);
120                 SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
121                 cmd.Parameters.Clear();
122                 return rdr;
123             }
124             catch
125             {
126                 conn.Close();
127                 throw;
128             }
129         }
130 
131         /// <summary>
132         /// 执行一条返回第一条记录第一列的SqlCommand命令,通过专用的连接字符串。 
133         /// 使用参数数组提供参数
134         /// </summary>
135         /// <remarks>
136         /// 使用示例:  
137         ///  Object obj = ExecuteScalar(connString, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));
138         /// </remarks>
139         /// <param name="connectionString">一个有效的数据库连接字符串</param>
140         /// <param name="commandType">SqlCommand命令类型 (存储过程, T-SQL语句, 等等。)</param>
141         /// <param name="commandText">存储过程的名字或者 T-SQL 语句</param>
142         /// <param name="commandParameters">以数组形式提供SqlCommand命令中用到的参数列表</param>
143         /// <returns>返回一个object类型的数据,可以通过 Convert.To{Type}方法转换类型</returns>
144         public static object ExecuteScalar(CommandType cmdType, string cmdText, params SqlParameter[] commandParameters)
145         {
146             SqlCommand cmd = new SqlCommand();
147             using (SqlConnection connection = new SqlConnection(connectionString))
148             {
149                 PrepareCommand(cmd, connection, null, cmdType, cmdText, commandParameters);
150                 object val = cmd.ExecuteScalar();
151                 cmd.Parameters.Clear();
152                 return val;
153             }
154         }
155 
156         /// <summary>
157         /// 执行一条返回第一条记录第一列的SqlCommand命令,通过已经存在的数据库连接。
158         /// 使用参数数组提供参数
159         /// </summary>
160         /// <remarks>
161         /// 使用示例: 
162         ///  Object obj = ExecuteScalar(connString, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));
163         /// </remarks>
164         /// <param name="conn">一个已经存在的数据库连接</param>
165         /// <param name="commandType">SqlCommand命令类型 (存储过程, T-SQL语句, 等等。)</param>
166         /// <param name="commandText">存储过程的名字或者 T-SQL 语句</param>
167         /// <param name="commandParameters">以数组形式提供SqlCommand命令中用到的参数列表</param>
168         /// <returns>返回一个object类型的数据,可以通过 Convert.To{Type}方法转换类型</returns>
169         public static object ExecuteScalar(SqlConnection connection, CommandType cmdType, string cmdText, params SqlParameter[] commandParameters)
170         {
171             SqlCommand cmd = new SqlCommand();
172             PrepareCommand(cmd, connection, null, cmdType, cmdText, commandParameters);
173             object val = cmd.ExecuteScalar();
174             cmd.Parameters.Clear();
175             return val;
176         }
177 
178         /// <summary>
179         /// 缓存参数数组
180         /// </summary>
181         /// <param name="cacheKey">参数缓存的键值</param>
182         /// <param name="cmdParms">被缓存的参数列表</param>
183         public static void CacheParameters(string cacheKey, params SqlParameter[] commandParameters)
184         {
185             parmCache[cacheKey] = commandParameters;
186         }
187 
188         /// <summary>
189         /// 获取被缓存的参数
190         /// </summary>
191         /// <param name="cacheKey">用于查找参数的KEY值</param>
192         /// <returns>返回缓存的参数数组</returns>
193         public static SqlParameter[] GetCachedParameters(string cacheKey)
194         {
195             SqlParameter[] cachedParms = (SqlParameter[])parmCache[cacheKey];
196             if (cachedParms == null)
197                 return null;
198             //新建一个参数的克隆列表
199             SqlParameter[] clonedParms = new SqlParameter[cachedParms.Length];
200             //通过循环为克隆参数列表赋值
201             for (int i = 0, j = cachedParms.Length; i < j; i++)
202                 //使用clone方法复制参数列表中的参数
203                 clonedParms[i] = (SqlParameter)((ICloneable)cachedParms[i]).Clone();
204             return clonedParms;
205         }
206 
207         /// <summary>
208         /// 为执行命令准备参数
209         /// </summary>
210         /// <param name="cmd">SqlCommand 命令</param>
211         /// <param name="conn">已经存在的数据库连接</param>
212         /// <param name="trans">数据库事物处理</param>
213         /// <param name="cmdType">SqlCommand命令类型 (存储过程, T-SQL语句, 等等。)</param>
214         /// <param name="cmdText">Command text,T-SQL语句 例如 Select * from Products</param>
215         /// <param name="cmdParms">返回带参数的命令</param>
216         private static void PrepareCommand(SqlCommand cmd, SqlConnection conn, SqlTransaction trans, CommandType cmdType, string cmdText, SqlParameter[] cmdParms)
217         {
218             //判断数据库连接状态
219             if (conn.State != ConnectionState.Open)
220                 conn.Open();
221             cmd.Connection = conn;
222             cmd.CommandText = cmdText;
223             //判断是否需要事物处理
224             if (trans != null)
225                 cmd.Transaction = trans;
226             cmd.CommandType = cmdType;
227             if (cmdParms != null)
228             {
229                 foreach (SqlParameter parm in cmdParms)
230                     cmd.Parameters.Add(parm);
231             }
232         }
233 
234         /// <summary>
235         /// 获取dataset数据
236         /// </summary>
237         /// <param name="sql"></param>
238         /// <returns></returns>
239         public static DataTable ExecuteDataTable(string sql)
240         {
241             using (SqlConnection conn = new SqlConnection(connectionString))
242             {
243                 SqlDataAdapter da = new SqlDataAdapter(sql, conn);
244                 DataTable dst = new DataTable();
245                 da.Fill(dst);
246                 return dst;
247             }
248         }
249     }
250 }
SqlHelper

 

Wolfy.BLL业务逻辑层中包含了一个用于继承的基类BaseBLL<T>和用户业务逻辑UserBLL类,这层依赖Wolfy.IDAL,Wolfy.Model,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.BLL
 8 {
 9     public class BaseBLL<T> where T : Wolfy.Model.UserModel, new()
10     {
11         protected Wolfy.IDAL.IBaseDAL<T> Dal;
12         public BaseBLL(string type)
13         {
14             //通过工厂得到 dal
15             Dal = Wolfy.FactoryDAL.DataAccess<Wolfy.IDAL.IBaseDAL<T>>.CreateDAL(type);
16         }
17         public virtual bool Add(T model)
18         {
19             return Dal.Add(model);
20         }
21         public virtual bool Delete(int ID)
22         { return Dal.Detele(ID); }
23         public virtual bool Update(T model)
24         { return Dal.Update(model); }
25         public virtual T GetModel(int ID)
26         {
27             return Dal.GetModel(ID);
28         }
29        
30     }
31 }
BaseBLL
技术分享
 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.BLL
 8 {
 9     public class UserBLL : BaseBLL<Wolfy.Model.UserModel>
10     {
11         private const string _Type = "UserDAL";
12         private Wolfy.IDAL.IUserDAL _DAL;
13         public UserBLL()
14             : base(_Type)
15         {
16             _DAL = base.Dal as Wolfy.IDAL.IUserDAL;
17             if (_DAL == null)
18             {
19                 throw new NullReferenceException(_Type);
20             }
21         }
22         public bool Exists(string userName)
23         {
24             return _DAL.Exists(userName);
25         }
26         public Model.UserModel Login(string name, string pwd)
27         { return _DAL.Login(name, pwd); }
28     }
29 }
UserBLL

 

web.config程序集名称,连接字符串配置

技术分享
 1 <?xml version="1.0" encoding="utf-8"?>
 2 <!--
 3   有关如何配置 ASP.NET 应用程序的详细信息,请访问
 4   http://go.microsoft.com/fwlink/?LinkId=169433
 5   -->
 6 <configuration>
 7   <system.web>
 8     <compilation debug="true" targetFramework="4.5" />
 9     <httpRuntime targetFramework="4.5" />
10 
11   </system.web>
12   <connectionStrings>
13     <add name="SqlConnect" connectionString="server=.;database=Test;uid=sa;pwd=sa"/>
14   </connectionStrings>
15 <appSettings>
16   <add key="DAL" value=http://www.mamicode.com/"Wolfy.DAL"/>
17 </appSettings>
18 </configuration>
web.config

 

测试

简单的ajax登录,web项目需引用Wolfy.BLL.dll和Wolfy.Model.dll和Wolfy.DAL.dll

技术分享
 1 <!DOCTYPE html>
 2 <html xmlns="http://www.w3.org/1999/xhtml">
 3 <head>
 4     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 5     <title>wolfy信息系统登录</title>
 6     <script type="text/javascript" src="Scripts/jquery-1.11.0.js"></script>
 7     <script type="text/javascript">
 8         $(function () {
 9             $("#btnLogin").click(function () {
10                 var name = $("#txtUserName").val();
11                 var pwd = $("#txtPwd").val();
12                 $.ajax({
13                     url: "Ashx/Login.ashx",
14                     data: "name=" + name + "&pwd=" + pwd,
15                     type: "Post",
16                     dataType: "text",
17                     success: function (msg) {
18                         if (msg == "1") {
19                             $("#divMsg").html("登录成功");
20                         } else if(msg=="2") {
21                             $("#divMsg").html("用户名或密码为空");
22                         } else if(msg=="3"){
23                             $("#divMsg").html("用户名不存在");
24                         } else {
25                             $("#divMsg").html("密码错误");
26                         }
27                     }
28 
29 
30                 });
31             });
32         });
33     </script>
34 </head>
35 <body>
36     <table>
37         <tr>
38             <td>用户名:</td>
39             <td><input type="text" id="txtUserName" name="name" value="admin" /></td>
40         </tr>
41         <tr>
42             <td>密码:</td>
43             <td><input type="password" id="txtPwd" name="name" value="admin" /></td>
44         </tr>
45         <tr>
46             <td colspan="2"><input type="button" id="btnLogin" name="name" value="登录" /></td>
47         </tr>
48     </table>
49     <div id="divMsg"></div>
50 </body>
51 </html>
Login.html
技术分享
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Web;
 5 
 6 namespace Wolfy.LoginDemo.Ashx
 7 {
 8     /// <summary>
 9     /// Login 的摘要说明
10     /// </summary>
11     public class Login : IHttpHandler
12     {
13 
14         public void ProcessRequest(HttpContext context)
15         {
16             context.Response.ContentType = "text/plain";
17             //接收用户名和密码
18             string name = context.Request["name"];
19             string pwd = context.Request["pwd"];
20             if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(pwd))
21             {
22                 context.Response.Write("2");
23             }
24             else
25             {
26                 BLL.UserBLL bll = new BLL.UserBLL();
27                 Model.UserModel model = new Model.UserModel();
28                 if (!bll.Exists(name))
29                 {
30                     context.Response.Write("3");
31                 }
32                 else
33                 {
34                     model = bll.Login(name, pwd);
35                     if (model != null)
36                     {
37                         //登录成功记入cookie
38                         context.Response.Cookies["n"].Value =http://www.mamicode.com/ name;
39                         context.Response.Cookies["n"].Expires = DateTime.Now.AddDays(7);
40                         context.Response.Cookies["p"].Value =http://www.mamicode.com/ pwd;
41                         context.Response.Cookies["p"].Expires = DateTime.Now.AddDays(7);
42                         context.Response.Write("1");
43                     }
44                 }
45 
46 
47 
48             }
49         }
50 
51         public bool IsReusable
52         {
53             get
54             {
55                 return false;
56             }
57         }
58     }
59 }
Login.ashx

 

结果
技术分享

 

[c#基础]使用抽象工厂实现三层 和反射