多层架构解析

多层架构解析

Web
BLL
IDAL
Model
DALFactory
NHDAL
根据PetShop3.0的框架:Web层只依赖于BLL和Model,也就是说web层调用BLL层方法返回的Model层定义的数据;BLL层依赖于IDAL,Model,这一层实际是使用IDAL中的方法组合为业务,并处理IDAL层返回的Model;IDAL定义了所有底层方法,给DAL层留下接口;Model定义了对象实体,只有属性没有方法,基本上可以作为抽象类定义。DALFactory的作用是根据配置文件中的设置动态取出取出数据访问层(Data
Access Layer)对象的实例,这样做就把实际使用的DAL跟BLL层分离,如果需要切换到其他DAL,只要修改此层就可以了。
本项目使用NH(NHibernate)作为DAl,所以命名为NHDAL。NHDAL依赖于Model,继承Model中属性的定义,并添加了NH需要用到的属性器。同时NHDAL实现IDAL中定义的方法。
下面是对登陆验证和储存日志的实例
先看看IDAL和Model中的定义吧
代码段一 IDAL接口定义
using System;

namespace CManager.IDAL.Log
{
    /**////


    /// ILoginLog 的摘要说明。
    ///

    public interface ISignLog
    {
        void LogSignIn( string userid, string sessionid, string clientip,
DateTime logindate );

        bool CheckPassword( string userid, string password);
    }
}

代码段二 Model对象定义

using System;

namespace CManager.Model.Log
{
    /**////


    /// LoginInfo 的摘要说明。
    ///

    public class SignLogInfo
    {
        public int SignLogID
        {
            get {return _SignLogID;}
        }
        public string UserID
        {
            get {return _UserID;}
        }
        public string SessionID
        {
            get {return _SessionID;}
        }
        public string ClientIP
        {
            get {return _ClientIP;}
        }
        public DateTime SignInDate
        {
            get {return _SignInDate;}
        }
        public DateTime SignOutDate
        {
            get {return _SignOutDate;}
        }

        protected int _SignLogID;
        protected string _UserID;
        protected string _SessionID;
        protected string _ClientIP;
        protected DateTime _SignInDate;
        protected DateTime _SignOutDate;
    }
}

然后是BLL中调用。因为BLL不依赖于任何DAL,所以通过中间层DALFactory创建DAL的实例,并通过IDAl定义的接口返回给BLL。
代码段三 BLL方法

using System;
using System.Collections;
using System.Web;

using CManager.Model.Log;
using CManager.Model.Collections;
using CManager.DALFactory.Log;
using CManager.IDAL.Log;


namespace CManager.BLL.Log
{
    public class Log
    {

        //未完成,应该返回Module.Log.Account
        public static bool Login ( string userid, string password, HttpContext
context )
        {
            ISignLog log = LogFactory.CreateSignLog();
            if (log.CheckPassword(userid,password))
            {
                log.LogSignIn( userid ,context.Session.SessionID,
context.Request.UserHostAddress, DateTime.Now );
                return true;
            }
            else
            {
                return false;
            }
        }
    }
}

代码段四 DALFactory方法

using System;
using CManager.IDAL.Log;
using System.Reflection;

namespace CManager.DALFactory.Log
{
    public class LogFactory
    {
        public static ISignLog CreateSignLog()
        {
            //获取web.config里DAL的设置
            string path =
System.Configuration.ConfigurationSettings.AppSettings["WebDAL"];
            //组合出类名
            string className = path + ".Log.SignLog";
            //运行时创建类实例,需要类实现实例化
            return (ISignLog) Assembly.Load(path).CreateInstance(className);
        }
    }
}
代码段五 web.config


   
 
     

type="System.Configuration.NameValueSectionHandler, System,
Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089" />
 
 
    value="NHibernate.Connection.DriverConnectionProvider" />
    value="NHibernate.Driver.SqlClientDriver" />
    value="server=127.0.0.1;database=CManager;uid=sa;pwd=;" />
   
   
 

   
       
       
       
       
 

 
                  
 

理论上Web层并不知道IDAL层定义的原子方法,只使用BLL层给出的方法。这就是所谓的业务层与表现层分开。Web层只接受用户发出的请求,然后处理参数交给BLL层,并对BLL层返回的结果进行判断返回给结果。
代码段六 Web层调用

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

using CManager.BLL.Log;
using CManager.Model.Log;

namespace BTTech.CManager.Web
{
    /**////


    /// Login 的摘要说明。
    ///

    public class Login : PageBase
    {
        protected System.Web.UI.WebControls.TextBox UserName;
        protected System.Web.UI.WebControls.TextBox Password;
        protected System.Web.UI.HtmlControls.HtmlInputImage ImageButton1;
   
        private void Page_Load(object sender, System.EventArgs e)
        {
           
        }

        private void ImageButton1_ServerClick(object sender,
System.Web.UI.ImageClickEventArgs e)
        {
            if (Log.Login( UserName.Text, Password.Text, this.Context))
                Response.Redirect("",true);
            else
                Alert("用户名或密码错误");
        }
    }
}

最后是本文的主角NHDAL了,虽然最后出现,却是所有实际操作的最终执行者。
代码段七 实现IDAL


using System;
using NHibernate.Cfg;
using NHibernate;

namespace CManager.NHDAL.Log
{
    /**////


    /// SignLog 的摘要说明。
    ///

    public class SignLog : NHObject,CManager.IDAL.Log.ISignLog
    {
        public SignLog()
        {
        }

        public void LogSignIn(string userid, string sessionid, string clientip,
DateTime logindate)
        {
            ISession session = CreateSession();
            session.Save(new SignLogInfo(userid, sessionid, clientip,
logindate));
        }

        public bool CheckPassword( string userid, string password)
        {//未完成
            return true;
        }
    }
}

代码段八 继承Model
using System;
using CManager.Model;

namespace CManager.NHDAL.Log
{
    /**////


    /// SignLog 的摘要说明。
    ///

    public class SignLogInfo : CManager.Model.Log.SignLogInfo
    {
        private int Id
        {
            get {return this._SignLogID;}
            set    {this._SignLogID = value;}
        }
        private string NH_UserID
        {
            get {return _UserID;}
            set {_UserID = value;}
        }
        private string NH_SessionID
        {
            get {return _SessionID;}
            set {_SessionID = value;}
        }
        private string NH_ClientIP
        {
            get {return _ClientIP;}
            set {_ClientIP = value;}
        }
        private DateTime NH_SignInDate
        {
            get {return _SignInDate;}
            set {_SignInDate = value;}
        }
        private DateTime NH_SignOutDate
        {
            get {return _SignOutDate;}
            set {_SignOutDate = value;}
        }

        private SignLogInfo()
        {

        }

        internal SignLogInfo(string userid, string sessionid, string clientip,
DateTime signdate )
        {
            this._UserID = userid;
            this._SessionID = sessionid;
            this._ClientIP = clientip;
            this._SignInDate = signdate;
            this._SignOutDate = signdate;
        }
    }
}

代码段九 影射文件  SignLogInfo.hbm.xml  这里用到上篇文章《不让NH属性器破坏封装》提到的方法


    table="CM_SignLog">
       
            unique="true" index="PK__CM_SignLog__79A81403"/>
           
       

       
            not-null="true"/>
       

       
            not-null="true"/>
       

       
            not-null="true"/>
       

       
           
       

       
           
       

   


代码段十 小技巧,NHObject基类
定义了一个NHObject的基类,因为任何实际操作对象is a NHObject,所以均继承这个类
这样做的好处是当我们需要更改加载连接字符串方法(比如解密)的时候只需在此出修改,还可以比较大面积地更改NH的使用方法。
using System;
using NHibernate;
using NHibernate.Cfg;

namespace CManager.NHDAL
{
    /**////


    /// NHConfigBase 的摘要说明。
    ///

    public class NHObject
    {
        private static Configuration config = new
Configuration().AddAssembly(System.Reflection.Assembly.Load("CManager.NHDAL"));
        private static ISessionFactory sessionFactory =
config.BuildSessionFactory();
        protected static NHibernate.ISession CreateSession()
        {
            return sessionFactory.OpenSession();
        }
    }
}

 这样一个完整的框架就成功地搭建并运行了。:)

你可能感兴趣的:(框架模式)