• MVC框架示例讲解[转]


    这是一个信息管理项目

    框架脱胎于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();
            }

        }

    }

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

  • 相关阅读:
    Ubuntu14.04下Sublime Text 3解决无法输入中文
    100% 解决wine中文乱码问题
    历史朝代顺序表
    HTTP状态码分类
    Kali Linux 2019
    多线程下载器(针对于百度云下载)
    百度云破解版&&第三方下载工具&&分享链接无需提取码直接下载
    MongoDB 4.0.10 GridFS操作
    MongoDB 4.0.10 游标
    MongoDB 4.0.10 用户管理
  • 原文地址:https://www.cnblogs.com/huashanlin/p/730516.html
Copyright © 2020-2023  润新知