MVC架構樣本

來源:互聯網
上載者:User

架構脫胎於PetShop3.0
分為如下幾層
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
{
    /**//// <summary>
    /// ILoginLog 的摘要說明。
    /// </summary>
    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
{
    /**//// <summary>
    /// LoginInfo 的摘要說明。
    /// </summary>
    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

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <!-- 這段大家都熟悉了 -->
  <configSections>
      <section name="nhibernate" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  </configSections>
  <nhibernate>
    <add key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider" />
    <add key="hibernate.connection.driver_class" value="NHibernate.Driver.SqlClientDriver" />
    <add key="hibernate.connection.connection_string" value="server=127.0.0.1;database=CManager;uid=sa;pwd=;" />
    <add key="hibernate.connection.isolation" value="ReadCommitted"/>
    <add key="hibernate.dialect" value="NHibernate.Dialect.MsSql2000Dialect" />
  </nhibernate>
    <appSettings>
        <!-- 預設顯示每頁顯示記錄數 -->
        <add key="DefaultRecordCount" value="20" />
        <!-- *資料庫層所在命名空間* 實際使用的DAL在這裡設定   -->
        <add key="WebDAL" value="CManager.NHDAL" />
  </appSettings>
  <system.web>
                <!-- 這段按下,不佔頁面了 -->  
 </system.web>

</configuration>

理論上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
{
    /**//// <summary>
    /// Login 的摘要說明。
    /// </summary>
    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
{
    /**//// <summary>
    /// SignLog 的摘要說明。
    /// </summary>
    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
{
    /**//// <summary>
    /// SignLog 的摘要說明。
    /// </summary>
    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屬性器破壞封裝》提到的方法

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
    <class name="CManager.NHDAL.Log.SignLogInfo, CManager.NHDAL" table="CM_SignLog">
        <id name="Id" type="Int32" unsaved-value="0">
            <column name="SignLogID" sql-type="int" not-null="true" unique="true" index="PK__CM_SignLog__79A81403"/>
            <generator class="native" />
        </id>
        <property name="NH_UserID" type="String">
            <column name="UserID" length="50" sql-type="nvarchar" not-null="true"/>
        </property>
        <property name="NH_SessionID" type="String">
            <column name="SessionID" length="24" sql-type="nvarchar" not-null="true"/>
        </property>
        <property name="NH_ClientIP" type="String">
            <column name="ClientIP" length="20" sql-type="nvarchar" not-null="true"/>
        </property>
        <property name="NH_SignInDate" type="DateTime">
            <column name="SignInDate" sql-type="datetime" not-null="true"/>
        </property>
        <property name="NH_SignOutDate" type="DateTime">
            <column name="SignOutDate" sql-type="datetime" not-null="false"/>
        </property>
    </class>
</hibernate-mapping>
程式碼片段十 小技巧,NHObject基類
定義了一個NHObject的基類,因為任何實際操作對象is a NHObject,所以均繼承這個類
這樣做的好處是當我們需要更改載入連接字串方法(比如解密)的時候只需在此出修改,還可以比較大面積地更改NH的使用方法。

using System;
using NHibernate;
using NHibernate.Cfg;

namespace CManager.NHDAL
{
    /**//// <summary>
    /// NHConfigBase 的摘要說明。
    /// </summary>
    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();
        }
    }
}

 這樣一個完整的架構就成功地搭建並運行了。:)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.