以下代码是从51aspx 下载的一个关于多层应用的bbs源码,由于个人认为它对多层应用是一个比较好的示范,所以想下决定搞懂它,希望哪位大侠有空能帮帮忙。
所有源码的下载url 
http://www.51aspx.com/downCode_51aspx/yyzqy_51aspx.rar
由于源码的作者比较忙,所以不便打扰他本人,只好到这里来求解。
另外分不够,可能加。真必求教各位。/***************Model**********************/
using System;namespace WeYyzyq.Model
{
    /// <summary>
    /// 用户基本信息实体类
    /// 创建时间:2006-8-8
    /// 创建者:郭华秋
    /// </summary>
    [Serializable]
    public class UserInfo
    {
        private string user_name;
        private string user_pwd;
        private string user_ask;
        private string user_answer;
        private string user_email;        /// <summary>
        /// 用户信息
        /// </summary>
        /// <param name="user_name">用户名</param>
        /// <param name="user_pwd">密码</param>
        /// <param name="user_ask">密码找回问题</param>
        /// <param name="user_answer">密码找回答案</param>
        /// <param name="user_email">电子邮件地址</param>
        public UserInfo(string user_name, string user_pwd, string user_ask, string user_answer, string user_email)
        {
            this.user_name = user_name;
            this.user_pwd = user_pwd;
            this.user_ask = user_ask;
            this.user_answer = user_answer;
            this.user_email = user_email;
        }                /// <summary>
        /// 用户名
        /// </summary>
        public string User_Name
        {
            get { return user_name; }
            set { user_name = value; }
        }        /// <summary>
        /// 密码
        /// </summary>
        public string User_Pwd
        {
            get { return user_pwd; }
            set { user_pwd = value; }        }        /// <summary>
        /// 密码找回问题
        /// </summary>
        public string User_Ask
        {
            get { return user_ask; }
            set { user_ask = value; }        }        /// <summary>
        /// 密码找回答案
        /// </summary>
        public string User_Answer
        {
            get { return user_answer; }
            set { user_answer = value; }
        }        /// <summary>
        /// 电子信箱
        /// </summary>
        public string User_Email
        {
            get { return user_email; }
            set { user_email = value; }
        }    }}/*********接口层*********************/
using System;
using System.Collections.Generic;
using WeYyzyq.Model;namespace WeYyzyq.IDAL
{
    /// <summary>
    /// 用户表接口
    /// 编写者:马先光
    /// 编写日期:2006-8-9
    /// </summary>
    public interface IUsers
    {
        /// <summary>
        /// 添加新用户
        /// </summary>
        /// <param name="user">用户实体类</param>
        /// <param name="userbase">用户基本信息实体类</param>
        string Add_User(UserInfo user, UserBaseInfo userbase);        /// <summary>
        /// 修改用户基本信息
        /// </summary>
        /// <param name="userbase">用户基本信息实体类</param>
        bool Change_UserBase(UserBaseInfo userbase);        /// <summary>
        /// 修改用户密码
        /// </summary>
        /// <param name="userid">用户ID</param>
        /// <param name="pwd">用户密码</param>
        /// <returns></returns>
        bool Change_UserPwd(string userid, string pwd);        /// <summary>
        /// 删除用户
        /// </summary>
        /// <param name="id">用户ID</param>
        bool Del_User(string userid);        /// <summary>
        /// 验证用户名是否可用
        /// </summary>
        /// <param name="username">用户名</param>
        /// <returns></returns>
        bool Vld_UserName(string username);        /// <summary>
        /// 验证用户登录信息
        /// </summary>
        /// <param name="username">用户名</param>
        /// <param name="password">密码</param>
        /// <param name="ip">IP地址</param>
        /// <returns></returns>
        string Vld_User(string username,string password,string ip);        /// <summary>
        /// 验证管理用户登录信息
        /// </summary>
        /// <param name="username">用户名</param>
        /// <param name="password">密码</param>
        /// <returns></returns>
        bool Vld_ManageUser(string username, string password);
        
        /// <summary>
        /// 通过用户ID获取用户基本信息
        /// </summary>
        /// <param name="userid">用户ID</param>
        /// <returns></returns>
        UserBaseInfo Get_UserBaseInfo(string userid);        /// <summary>
        /// 获取全部用户信息
        /// </summary>
        /// <returns></returns>
        IList<UserDetailsInfo> Get_UserDatailsInfo();        /// <summary>
        /// 获取指定用户详细信息
        /// </summary>
        /// <param name="userid">用户ID</param>
        /// <returns></returns>
        IList<UserDetailsInfo> Get_UserDatailsInfo(string userid);        /// <summary>
        /// 获取全部用户信息
        /// </summary>
        /// <param name="order">排序</param>
        /// <returns></returns>
        IList<UserDetailsInfo> Get_AllUserDatailsInfo(string order);        /// <summary>
        /// 修改用户最后登录时间
        /// </summary>
        /// <param name="userid">会员ID</param>
        void ChangeUserLastLoginDate(string userid);        /// <summary>
        /// 添加新访客
        /// </summary>
        /// <param name="ip"></param>
        bool AddGuest(string ip);        /// <summary>
        /// 修改访客最后登录时间
        /// </summary>
        /// <param name="ip">访客ID</param>
        void ChangeGuestLastLoginDate(string ip);
                
    }
}

解决方案 »

  1.   

    /****************数据层工厂类*************/
    using System;
    using System.Reflection;
    using System.Configuration;namespace WeYyzyq.DALFactory
    {
        /// <summary>
        /// 数据层工厂类
        /// 编写者:马先光
        /// 编写日期:2006-8-7
        /// </summary>
        public sealed class DataAccess
        {
            private static readonly string path = ConfigurationManager.AppSettings["WebDAL"];        /// <summary>
            /// 创建IUser接口类
            /// </summary>
            /// <returns></returns>
            static public WeYyzyq.IDAL.IUsers CreateUsers()
            {
                string className = path + ".Users";
                return (WeYyzyq.IDAL.IUsers)Assembly.Load(path).CreateInstance(className);
            }        /// <summary>
            /// 创建IBbs_MenuBig接口类
            /// </summary>
            /// <returns></returns>
            static public WeYyzyq.IDAL.IBbs_MenuBig CreateBbs_MenuBig()
            {
                string className = path + ".Bbs_MenuBig";
                return (WeYyzyq.IDAL.IBbs_MenuBig)Assembly.Load(path).CreateInstance(className);
            }        /// <summary>
            /// 创建IBbs_MenuSmall接口类
            /// </summary>
            /// <returns></returns>
            static public WeYyzyq.IDAL.IBbs_MenuSmall CreateBbs_MenuSmall()
            {
                string className = path + ".Bbs_MenuSmall";
                return (WeYyzyq.IDAL.IBbs_MenuSmall)Assembly.Load(path).CreateInstance(className);
            }        /// <summary>
            /// 创建IBbs_Post接口类
            /// </summary>
            /// <returns></returns>
            static public WeYyzyq.IDAL.IBbs_Post CreateBbs_Post()
            {
                string className = path + ".Bbs_Post";
                return (WeYyzyq.IDAL.IBbs_Post)Assembly.Load(path).CreateInstance(className);
            }        /// <summary>
            /// 创建IBbs_PostBack接口类
            /// </summary>
            /// <returns></returns>
            static public WeYyzyq.IDAL.IBbs_PostBack CreateBbs_PostBack()
            {
                string className = path + ".Bbs_PostBack";
                return (WeYyzyq.IDAL.IBbs_PostBack)Assembly.Load(path).CreateInstance(className);
            }        /// <summary>
            /// 创建IBbs_Message
            /// </summary>
            /// <returns></returns>
            static public WeYyzyq.IDAL.IBbs_Message CreateBbs_Message()
            {
                string className = path + ".Bbs_Message";
                return (WeYyzyq.IDAL.IBbs_Message)Assembly.Load(path).CreateInstance(className);
            }        /// <summary>
            /// 创建IBbs_SiteInfo
            /// </summary>
            /// <returns></returns>
            static public WeYyzyq.IDAL.IBbs_SiteInfo CreateBbs_SiteInfo()
            {
                string className = path + ".Bbs_SiteInfo";
                return (WeYyzyq.IDAL.IBbs_SiteInfo)Assembly.Load(path).CreateInstance(className);
            }        /// <summary>
            /// 创建IBbs_PostType
            /// </summary>
            /// <returns></returns>
            static public WeYyzyq.IDAL.IBbs_PostType CreateBbs_PostType()
            {
                string className = path + ".Bbs_PostType";
                return (WeYyzyq.IDAL.IBbs_PostType)Assembly.Load(path).CreateInstance(className);
            
            }        /// <summary>
            /// 创建IBbs_Link
            /// </summary>
            /// <returns></returns>
            static public WeYyzyq.IDAL.IBbs_Link CreateBbs_Link()
            {
                string className = path + ".Bbs_Link";
                return (WeYyzyq.IDAL.IBbs_Link)Assembly.Load(path).CreateInstance(className);
            }
        }
    }
      

  2.   


    /******************逻辑层*************************/
    using System;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.HtmlControls;
    using System.Text.RegularExpressions;
    using WeYyzyq.Comp;
    using WeYyzyq.Model;
    using WeYyzyq.IDAL;
    using WeYyzyq.DALFactory;namespace WeYyzyq.Logic
    {
        /// <summary>
        /// 用户业务逻辑类
        /// 编写者:马先光
        /// 编写日期:2006-8-9
        /// </summary>
        public class Users 
        {
            IUsers user = DataAccess.CreateUsers();        /// <summary>
            /// 添加用户信息
            /// </summary>
            /// <param name="txtName">用户名</param>
            /// <param name="txtPwd">密码</param>
            /// <param name="ddlAsk">密码问题</param>
            /// <param name="txtAnswer">密码答案</param>
            /// <param name="txtEmail">电子邮件</param>
            /// <param name="ckbSex">性别</param>
            /// <param name="txtBirthday">生日</param>
            /// <param name="txtSeat">所在地</param>
            /// <param name="txtOicq">QQ</param>
            /// <param name="txtMsn">MSN</param>
            /// <param name="txtPic">头像地址</param>
            /// <param name="txtInk">个性签名</param>
            public void AddUser(string name, string pwd, string ask,string answer, string email,
                string sex, string birthday, string seat,string oicq, string msn, string pic, string ink)
            {
                name = StringUtil.InputText(name, 10);
                pwd = StringUtil.EncryptPassword(pwd, StringUtil.PasswordType.MD5.ToString());
                answer = StringUtil.InputText(answer, 50);
                email = StringUtil.InputText(email, 100);            
                DateTime dtbirthday = (birthday.Length > 0) ? Convert.ToDateTime(StringUtil.InputText(birthday, 10)) : DateTime.Now.AddYears(-20);
                seat = StringUtil.InputText(seat, 50);
                msn = StringUtil.InputText(msn, 100);
                pic = StringUtil.InputText(pic, 200);            if (user.Vld_UserName(name))
                {
                    string userid = user.Add_User(new UserInfo(name, pwd, ask, answer, email),
                        new UserBaseInfo(0, sex, dtbirthday, seat, oicq, msn, pic, ink));
                    HttpContext.Current.Response.Cookies.Add(new HttpCookie("userid", userid));
                    HttpContext.Current.Response.Cookies.Add(new HttpCookie("username", HttpUtility.UrlEncode(name)));                                
                    HttpContext.Current.Response.Redirect(HttpContext.Current.Session["history"].ToString());
                }
                else
                    Jscript.Alert("用户名重复!请检测用户名后注册!");
            }        /// <summary>
            /// 修改用户密码
            /// </summary>
            /// <param name="strPwd">用户密码</param>
            public void Change_UserPwd( string strPwd)
            {
                strPwd = StringUtil.EncryptPassword(StringUtil.InputText(strPwd, 100), StringUtil.PasswordType.MD5.ToString());
                user.Change_UserPwd(UsersInfo.GetUserId,strPwd);
            }        /// <summary>
            /// 修改用户基本信息
            /// </summary>
            /// <param name="strUserId">ID</param>
            /// <param name="strSex">性别</param>
            /// <param name="strBirthday">生日</param>
            /// <param name="strSeat">所在地</param>
            /// <param name="strOicq">QQ</param>
            /// <param name="strMsn">MSN</param>
            /// <param name="strPic">头像地址</param>
            /// <param name="strInk">个性签名</param>
            public void ChangeUserBase(int intUserId,string strSex,string strBirthday,string strSeat,
                string strOicq ,string strMsn,string strPic,string  strInk)
            {
                DateTime dtBirthday = Convert.ToDateTime(StringUtil.InputText(strBirthday,10));
                strSeat = StringUtil.InputText(strSeat,50);            
                strMsn = StringUtil.InputText(strMsn,100);
                strPic = StringUtil.InputText(strPic,200);
                strInk = StringUtil.InputText(StringUtil.GetHtmlEditReplace(strInk),4000);
                user.Change_UserBase(new UserBaseInfo(intUserId, strSex, dtBirthday, strSeat, strOicq, strMsn, strPic, strInk));
            }        /// <summary>
            /// 用户登录
            /// </summary>
            /// <param name="strUserName">用户名</param>
            /// <param name="strPassWord">密码</param>
            /// <param name="day">保存登录信息天数</param>
            /// <param name="ip">IP地址</param>
            public void VldUserLogin(string strUserName, string strPassWord, int day,string ip)
            {            
                string strResult = user.Vld_User(StringUtil.InputText(strUserName,10),StringUtil.EncryptPassword(strPassWord,StringUtil.PasswordType.MD5.ToString()),ip);
                if (Equals(strResult, ""))
                    Jscript.Alert("用户名或密码不正确!");
                else
                {
                    HttpContext.Current.Response.Cookies.Add(new HttpCookie("userid", strResult));  
                    HttpContext.Current.Response.Cookies.Add(new HttpCookie("username", HttpUtility.UrlEncode(strUserName)));                
                    if(!Equals(day,0))
                    {
                        HttpContext.Current.Request.Cookies["userid"].Expires = DateTime.Now.AddDays(day);
                        HttpContext.Current.Request.Cookies["username"].Expires = DateTime.Now.AddDays(day);       
                    }
                    HttpContext.Current.Response.Redirect(HttpContext.Current.Session["history"].ToString());
                }
            }        /// <summary>
            /// 管理用户登录
            /// </summary>
            /// <param name="strUserName">用户名</param>
            /// <param name="strPassWord">密码</param>
            /// <param name="Memory">是否保存登录信息</param>
            public void VldManageUserLogin(string strUserName, string strPassWord, bool Memory)
            {
                if (!user.Vld_ManageUser(StringUtil.InputText(strUserName, 10), StringUtil.EncryptPassword(strPassWord, StringUtil.PasswordType.MD5.ToString())))
                    Jscript.Alert("用户名或密码不正确!");
                else
                {
                    HttpContext.Current.Response.Cookies.Add(new HttpCookie("ManageId", HttpUtility.UrlEncode(strUserName)));
                    System.Web.Security.FormsAuthentication.RedirectFromLoginPage(strUserName, false);
                    if (Memory)
                    {
                        HttpContext.Current.Request.Cookies["ManageId"].Expires = DateTime.MaxValue;
                    }
                    HttpContext.Current.Response.Redirect("ManageMain.aspx");
                }
            }
            /// <summary>
            /// 验证用户名是否可用
            /// </summary>
            /// <param name="lblMessage">显示消息的标签控件</param>
            /// <param name="strUserName">用户名</param>
            public void VldUserName(Label lblMessage, string strUserName)
            {
                string vldLength = Regex.Replace(strUserName, "[\u4e00-\uf900]", "aa");
                if (vldLength.Length < 6 || vldLength.Length > 16)
                    lblMessage.Text = "用户名长度必须大于6并且小于16";
                else
                    lblMessage.Text = (user.Vld_UserName(strUserName)) ? "恭喜您,该用户名没有被注册,请放心注册!" : "很抱歉,该用户名已经被注册,请重新选择!";
            }
      

  3.   

    ................
    /**************SQL层*************/
    using System;
    using System.Data;
    using System.Data.SqlClient;
    using System.Collections.Generic;
    using WeYyzyq.IDAL;
    using WeYyzyq.Model;
    using WeYyzyq.DBUtility;namespace WeYyzyq.SQLDAL
    {
        /// <summary>
        /// 用户接口实现类
        /// 编写者:马先光
        /// 编写日期:2006-8-9
        /// </summary>
        public class Users :SqlDataBase,IUsers
        {
            private const string USER_ID = "@User_Id";
            private const string USER_NAME = "@User_Name";
            private const string USER_PWD = "@User_Pwd";
            private const string USER_ASK = "@User_Ask";
            private const string USER_ANSWER = "@User_Answer";
            private const string USER_EMAIL = "@User_Email";
            private const string USER_IP = "@User_Ip";
            private const string USERBASE_USERID = "@UserBase_UserId";
            private const string USERBASE_SEX = "@UserBase_Sex";
            private const string USERBASE_BIRTHDAY = "@UserBase_Birthday";
            private const string USERBASE_SEAT = "@UserBase_Seat";
            private const string USERBASE_OICQ = "@UserBase_Oicq";
            private const string USERBASE_MSN = "@UserBase_Msn";
            private const string USERBASE_PIC = "@UserBase_Pic";
            private const string USERBASE_INK = "@UserBase_Ink";
                   
            string strSql = null;
            SqlDataReader sdr = null;       /// <summary>
           /// 添加用户帐号信息
           /// </summary>
           /// <param name="user"></param>
            public string Add_User(UserInfo user,UserBaseInfo userbase)
            {
                SqlParameter[] prams = {
                    MakeInParam(USER_NAME,SqlDbType.VarChar,20,user.User_Name),
                    MakeInParam(USER_PWD,SqlDbType.VarChar,50,user.User_Pwd),
                    MakeInParam(USER_ASK,SqlDbType.VarChar,100,user.User_Ask),
                    MakeInParam(USER_ANSWER,SqlDbType.VarChar,100,user.User_Answer),
                    MakeInParam(USER_EMAIL,SqlDbType.VarChar,50,user.User_Email),
                    MakeInParam(USERBASE_SEX,SqlDbType.VarChar,10,userbase.UserBase_Sex), 
                    MakeInParam(USERBASE_BIRTHDAY,SqlDbType.DateTime,8,userbase.UserBase_Birthday),
                    MakeInParam(USERBASE_SEAT,SqlDbType.VarChar,200,userbase.UserBase_Seat),
                    MakeInParam(USERBASE_OICQ,SqlDbType.VarChar,15,userbase.UserBase_Oicq),
                    MakeInParam(USERBASE_MSN,SqlDbType.VarChar,200,userbase.UserBase_Msn),
                    MakeInParam(USERBASE_PIC,SqlDbType.VarChar,200,userbase.UserBase_Pic),
                    MakeInParam(USERBASE_INK,SqlDbType.VarChar,1000,userbase.UserBase_Ink),
                    MakeOutParam(USER_ID,SqlDbType.Int,4)
                };
                try
                {
                    RunProc("Up_Add_Users", prams);
                    return prams[12].Value.ToString();
                }
                catch { return "0"; }
            }        /// <summary>
            /// 修改用户信息
            /// </summary>
            /// <param name="userbase"></param>
            public bool Change_UserBase(UserBaseInfo userbase)
            {
                SqlParameter[] prams ={
                    MakeInParam(USERBASE_USERID,SqlDbType.Int,4,userbase.UserBase_Id),
                    MakeInParam(USERBASE_SEX,SqlDbType.VarChar,10,userbase.UserBase_Sex), 
                    MakeInParam(USERBASE_BIRTHDAY,SqlDbType.DateTime,8,userbase.UserBase_Birthday),
                    MakeInParam(USERBASE_SEAT,SqlDbType.VarChar,200,userbase.UserBase_Seat),
                    MakeInParam(USERBASE_OICQ,SqlDbType.VarChar,15,userbase.UserBase_Oicq),
                    MakeInParam(USERBASE_MSN,SqlDbType.VarChar,200,userbase.UserBase_Msn),
                    MakeInParam(USERBASE_PIC,SqlDbType.VarChar,200,userbase.UserBase_Pic),
                    MakeInParam(USERBASE_INK,SqlDbType.VarChar,1000,userbase.UserBase_Ink)
                };
                try
                {
                    RunProc("Up_Change_UserBase", prams);
                    return true;
                }
                catch { return false; }
            }...................
    问题:
    1.这几个层之间的关系是如调用的,看后有点思路,但不能确认是否正确(50分)
    2.数据层工厂类--这层的作是什么,不看明白?(50分)
    3.谁能有空比较详细对整支程序的逻辑做一个说明,让对实休类>>>抽象类>>>接口 不太理解的人能通过
    此程序能搞清楚(300分,另外开贴),所以源码到上述url中下载,如无法下载的,请用短信通知,我可以
    发。
      

  4.   

    1
    UI->BLL->DAL
    DAL里。包括工程,接口等2
    工厂是生成数据库连接的,负责创建数据库连接,是Oracle还是SQLserver。3
    没研究过这个源码,研究的是Petshop,推荐好文:
    浅谈“三层结构”原理与用意,自己搜一下吧,文章好长,尤其看看接口工厂那里,对人很有启发。
      

  5.   

    楼主去看看李天平的Blog就会明白的
      

  6.   

    李天平的Blog
    http://ltp.cnblogs.com/
      

  7.   

    给RMB我就告诉你
    但是为了弄明白这个我几乎2个月没怎么吃饭
    NND
      

  8.   

    看看这个
    http://blog.csdn.net/Afritxia/archive/2006/01/20/584672.aspx
    能不能给你点启发
      

  9.   

    To silkstockings,
    我担心给了你RMB ,也提不清楚。
    “但是为了弄明白这个我几乎2个月没怎么吃饭”???
      

  10.   

    哈哈,谢谢redfox241() ,已大至把AfritXia 的浅谈“三层结构”原理与用意看了一下。原来我下载的这个例子的结构就是AfritXia 的浅谈“三层结构”原理与用意的翻版。现次谢谢!
      

  11.   

    Eray(黑桃六),redfox241()  来接份。
    http://community.csdn.net/Expert/topic/5537/5537592.xml?temp=.4083521
      

  12.   

    Eray(黑桃六),redfox241()  来接份。http://community.csdn.net/Expert/topic/5540/5540100.xml?temp=.286709
      

  13.   

    1各层的关系:界面层(UI)层调用业务逻辑层(BLL),业务逻辑层通过工厂类调用SQL层,返回的是SQL层实现的接口,而各层之间之间是通过实体来传递的。2工厂顾名思义就是生产东西的,那生产的是什么呢?如果是鞋厂那就是生产的鞋,根据生产线的不同可能出来皮鞋或者旅游鞋,鞋厂就是工厂类,鞋就是接口,皮鞋就是SQL Server的数据层,旅游鞋就是Oracle的数据层。这样只要再添加一条DB2的生产线,就会出来DB2的数据层,也就是方便支持多数据库(典型的抽象工厂模式应用)。3太麻烦了,还是自己研究吧。这个的结构和PetShop很象,你也可以顺便研究一下。