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

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 }

 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 }

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="Wolfy.DAL"/>
17 </appSettings>
18 </configuration>

测试

简单的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>

 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 = name;
39                         context.Response.Cookies["n"].Expires = DateTime.Now.AddDays(7);
40                         context.Response.Cookies["p"].Value = 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 }

结果

源码下载:http://pan.baidu.com/s/1hqqSUrU

总结

参考文章:http://www.cnblogs.com/cmsdn/p/3494461.html

参考着这篇文章,敲了一遍,实践了一下。在博客园,虽然有很多提供代码的园友,但是自己动手实践一下,就可以发现其中好与不好的地方,也可以加深理解。

博客地址: http://www.cnblogs.com/wolf-sun/
博客版权: 本文以学习、研究和分享为主,欢迎转载,但必须在文章页面明显位置给出原文连接。
如果文中有不妥或者错误的地方还望高手的你指出,以免误人子弟。如果觉得本文对你有所帮助不如【推荐】一下!如果你有更好的建议,不如留言一起讨论,共同进步!
再次感谢您耐心的读完本篇文章。

转载:http://www.cnblogs.com/wolf-sun/p/3562156.html

时间: 2024-10-31 01:49:42

[c#基础]使用抽象工厂实现三层的相关文章

三层加抽象工厂加反射加配置文件加SqlHelper

              三层的例子敲的差不多了,为了对抽象工厂有个更好的理解,开始对三层进行加工,下面来对三层进行逐步更新,首先是看一下我画的包图:                             包图为大家从宏观上展示了程序各层之间的调用关系,现在用类图展示一下详细的调用关系:                            通过包图和类图能够比较清晰的知道各个包之间的调用关系,通过时序,可以清晰的知道这些调用关系的顺序,我们在写代码的时候是从D层开始写的,当然没有那么绝对,

.NET抽象工厂模式微理解:教你在项目中实现抽象工厂

最近在学习MVC,对于MVC里面的一些项目上的东西都和抽象模式有关,今天就微说明一下个人对于抽象工厂模式的理解,以方便学习MVC及工厂模式相关的同事和博友们理解.不足之处,还请斧正! 首先简单阐述一些三层的关系,相信观看该文章的博友们对于三层设计早已经是烂熟于心了,我这边就简单说明一下: 用户界面表示层(Web) 业务逻辑层(BLL) 数据访问层(DAL) 1:数据数据访问层:主要是对原始数据(数据库或者文本文件等存放数据的形式)的操作层,而不是指原始数据,也就是说,是对数据的操作,而不是数据库

简单工厂、工厂方法、抽象工厂模式

           最近一直再将设计模式,于是趁热打铁,对这三种设计模式做一个总结.           首先我先用一句话总结一下这三个模式:简单工厂是一个工厂只能造一种奔驰,工厂方法是一个工厂可以造多种车,比如劳斯莱斯.奥迪等,而抽象工厂是说工厂不光可以造越野式奔驰,还可以造家用式奔驰.还有商用式奔驰.            那么究竟简单工厂是什么呢?为什么它不是23的设计模式中的一个?            用一个类图和一段代码我们来解释一下:                      

炒冷饭系列:设计模式 抽象工厂模式

一.什么是抽象工厂模式 抽象工厂模式是所有形态的工厂模式中最为抽象和最其一般性的.抽象工厂模式可以向客户端 提供一个接口,使得客户端在不必指定产品的具 体类型的情况下,能够创建多个产品族的产品对象. 产品族和产品等级结构. 二.模式中包含的角色及其职责 1.抽象工厂(Creator)角色 抽象工厂模式的核心,包含对多个产品结构的声明,任何工厂类都必须实现这个接口. 2.具体工厂( Concrete Creator)角色 具体工厂类是抽象工厂的一个实现,负责实例化某个产品族中的产品对象. 3.抽象

创建型模式--抽象工厂模式

工厂三兄弟之抽象工厂模式(一) 工厂方法模式通过引入工厂等级结构,解决了简单工厂模式中工厂类职责太重的问题,但由于工厂方法模式中的每个工厂只生产一类产品,可能会导致系统中 存在大量的工厂类,势必会增加系统的开销.此时,我们可以考虑将一些相关的产品组成一个"产品族",由同一个工厂来统一生产,这就是我们本文将要学习的抽 象工厂模式的基本思想. 界面皮肤库的初始设计 Sunny 软件公司欲开发一套界面皮肤库,可以对 Java 桌面软件进行界面美化.为了保护版权,该皮肤库源代码不打算公开,而只

简单工厂、工厂方法、抽象工厂、策略模式、策略与工厂的区别

[本文转自简单工厂.工厂方法.抽象工厂.策略模式.策略与工厂的区别] 结合简单示例和UML图,讲解工厂模式简单原理. 一.引子 话说十年前,有一个爆发户,他家有三辆汽车(Benz(奔驰).Bmw(宝马).Audi(奥迪)),还雇了司机为他开车.不过,爆发户坐车时总是这样:上Benz车后跟司机说"开奔驰车!",坐上Bmw后他说"开宝马车!",坐上 Audi后他说"开奥迪车!".你一定说:这人有病!直接说开车不就行了?!而当把这个爆发户的行为放到我们

asp.net-Asp.Net抽象工厂 通过反射获取配置文件信息,为什么DAL层的dll文件无法生成到UI层,而简单工厂可以?

问题描述 Asp.Net抽象工厂 通过反射获取配置文件信息,为什么DAL层的dll文件无法生成到UI层,而简单工厂可以? 使用抽象工厂三层做程序的时候,程序报错"系统找不到指定的文件".网上百度后,把DAL层生成dll的路径指向UI层的bin目录下,问题解决.程序能正常读取数据库数据.解决完这个问题后,我写了一个简单三层程序,发现简单三层的程序,运行的时候,DAL层的dll文件能自动生成到UI层,不需要修改DAL层的指向路径.请问,抽象工厂三层出现这个问题的原因是什么?为什么简单三层不

设计模式系列之三:抽象工厂模式

前言 在设计模式有三个模式是与工厂模式相关的,分别是:简单工厂模式.工厂方法模式以及抽象工厂模式.在前面的文章中已经谈到前面两种,这里就对抽象工厂模式介绍一下.抽象工厂模式就是提供一个创建一系列相关或者相互依赖的接口(也就是抽象类),而无需指定具体的类.简单来说,就是当我们需要创建一个具体的对象的时候,我们不必指定该具体的对象,只需要使用它的上层接口直接调用就行.好像还是很抽象哦,好吧,为了更清晰领悟这个设计模式,我们还是通过一个案例来说明 问题背景 某公司开发了一个A软件,数据库使用的是SQL

设计模式之四(抽象工厂模式第一回合)

原文:设计模式之四(抽象工厂模式第一回合) 前言 首先关于抽象工厂模式的学习,我们需要慢慢的,由浅入深的进入.不能单刀直入,否则可能达不到预期学明白的目标. 第一回合  首先我们从最简单的数据访问程序开始吧. 下面先来看一个简单的小例子,代码很简单 public class User { public int ID{get;set;} public string Name{get;set;} } 一个简单的实体类,也相当于在SqlServer数据库中建立了相同的数据表 public class