例子说明修改bm

[MaxLabs.bbsMax]
逻辑层,用来放 单个实体类(Entity)、实体集合类(Collection) 、抽象类(Dao)、逻辑处理类(BO)

单个实体类(Entity)、实体集合类(Collection)都放在“Features” \ 对象名 \ “Entities” 目录下。

 按照bbsmax的框架结构,实体的集合,都应放在 实体集合类(Collection)中,它类似于(List<TV>). 实现了:
 “ICollection<TV>“, ”IComparable<TK> ,“IPrimaryKey<TK>”,"IEnumerable", "IEnumerable<TV>"接口.
 因此它:
 1.可迭代、枚举
 2.可对比
 
  它内部是用一个List<TV>泛型实例存放对象(实例名innerList)
 List<TV> innerList;
 它包含一个int下标的类索引
 public virtual TV this[int index]
 
 还包含名为Count的 get访问器<int>,以返回List<TV>的数据条数。
 public virtual int Count
 {
  get { return innerList.Count; }
 }
 
 
 因此它:
 1.可通过for int递增循环访问。
 2.可通过int类型的下标访问。
 3.它不可以通过TK(如string key)键索引的方式访问,因为 List<TV>只能通过int下标访问。


抽象类(Dao) ,用于存放对诸如帖子、板块 的数据访问抽象方法,都放在“Features” \ 对象名 \  “DataAccess” 目录下。
BO类,用于调用各 抽象类(Dao)的实现类实例。

以上类全部是实例类。


[MaxLabs.bbsMax.Web]
界面层,Web项目,在 bbsmax[5.1008]版本中,各aspx页面的后置代码都放在 "_codes"文件夹下 。

bbsmax的每一个aspx页面的后置代码都继承自一个PageBase(页面基类)。
如论坛首页"index.aspx","default.aspx" 页面的后置代码:
//_Default论坛index.aspx首页的后置代码,继承了bbs页面基类
public partial class _Default : AppBbsPageBase
{
 //省略无关代码...
}

//bbs页面基类 
public class BbsPageBase : WebEngine.PageBase 

 //论坛板块集合访问器 
 protected ForumCollection ForumCatalogs 
 { 
  get{ 
   if (m_ForumCatalogs == null) 
   { 
    //调用对应逻辑类(BO)实例的对应查询方法 
    m_ForumCatalogs = ForumBO.Instance.GetCategories(); 
   } 
   return m_ForumCatalogs; 
  } 
 } 
}

这样继承之后,我在"index.aspx" 页面就能获取到“ForumCatalogs”变量了,我只要遍历它,就能在页面上显示所有板块信息了。
既然如此,那么对应" default.aspx "模板代码里的以下代码:
<!--[if $ForumCatalogs.Count > 0]-->
<!--[loop $forumCatalog in $ForumCatalogs with $LoopIndex]-->
<a href="$url($forumCatalog.CodeName/list-1)">$forumCatalog.ForumName</a>
<!--[/loop]-->
<!--[/if]-->


[MaxLabs.bbsMax.DataAccess.SqlServer]
数据访问层, 实现" [MaxLabs.bbsMax]"层 的抽象类中的抽象方法,操控数据库。 


项目介绍完毕。
------

整个过程如下:
1.新建一个数据表,用来存放所需数据。
2.创建一个 对应的实例类和 实例集合类。
3.创建一个抽象类(Dao),用于存放查询数据库的抽象方法。
4.创建一个数据库访问类, 实现" [MaxLabs.bbsMax]"层 的抽象类中的抽象方法。
5.创建一个逻辑类 (BO) ,调用抽象类(Dao)的实现类实例 。
6.在"BbsPageBase"页面基类添加一个对应的集合变量访问器,访问器的get方法就是返回查询到的数据。
7.在模板中调用该访问器。

代码:
using System;
using System.Collections.Generic;
using System.Text;
using MaxLabs.bbsMax.Enums;
using MaxLabs.bbsMax.DataAccess;
using MaxLabs.bbsMax.Settings;
 
namespace MaxLabs.bbsMax.Entities
{
    /// <summary>
    /// 全局模板变量[实体类]
    /// </summary>
    public class TemplateVar : IPrimaryKey<string>
    {
        string _hash;
        string _value;
        int _tvarid;
 
        public TemplateVar()
        {
            _hash = string.Empty;
            _value = string.Empty;
            _tvarid = -1;
        }
 
        /// <summary>
        /// 从数据库data对象中,取出数据,封装为对象。
        /// </summary>
        /// <param name="__readerWrap"></param>
        public TemplateVar(DataReaderWrap __readerWrap)
        {
            _tvarid = __readerWrap.Get<int>("tvarid");
            _value = __readerWrap.Get<string>("value");
            _hash = __readerWrap.Get<string>("hash");
        }
 
        /// <summary>
        /// 对应数据表字段[hash]
        /// </summary>
        public string Hash
        {
            get { return _hash; }
            set { _hash = value; }
        }
 
        /// <summary>
        /// 对应数据表字段[value]
        /// </summary>
        public string Value
        {
            get { return _value; }
            set { _value = value; }
        }
 
        /// <summary>
        /// 对应数据表字段[tvarid]
        /// </summary>
        public int Tvarid
        {
            get { return _tvarid; }
            set { _tvarid = value; }
        }
 
        /// <summary>
        /// 重写ToString()方法,这里很重要。
        /// </summary>
        /// <returns>用户自定义的变量值</returns>
        public override string ToString()
        {
            return _value;
        }
 
        //这个可以无视
        #region IPrimaryKey<string> 成员
 
        public string GetKey()
        {
            return _hash;
        }
 
        #endregion
 
    }
}

由于我们需要通过 string key/键 的方式来得到“全局模板变量”实体对象的值,因此,bbsmax框架的 “实体集合”类是不适合的,
我们需要自己写支持通过string key/键 “实体集合类” 来存放“全局模板变量”。
我们可以直接用.net 自带的 键/值 字典集合 Dictionary<string,TemplateVar> 类,它支持通过 string key/键 的方式来得到“全局模板变量”实体对象的值 不过这样显然与bbsmax的框架格格不入,因此,我们自己写  “实体集合类”。


你要知道,它的本质就是基于 Dictionary<TK, TV>,只不过是一个 Dictionary<TK, TV>的再次封装,这样虽然更麻烦,但会变得很灵活,和可扩展,比如:你可以在自定义的  “实体集合类” 里面加一个“只读”属性。

using System;
using System.Collections;
using System.Collections.Generic;
 
namespace MaxLabs.bbsMax.Entities
{
    /// <summary>
    ///  基于键/值的字典集合
    /// </summary>
    /// <typeparam name="TK">键</typeparam>
    /// <typeparam name="TV">值</typeparam>
    public abstract class EntityDictionaryBase<TK, TV> : IDictionary<TK, TV>, IEnumerable, IEnumerable<KeyValuePair<TK, TV>>
    {
        private bool m_IsReadOnly = false;
 
        bool _isIgnoreItemNotExist;
 
        //集合
        Dictionary<TK, TV> dictionay;
 
        public EntityDictionaryBase()
        {
            dictionay = new Dictionary<TK, TV>();
        }
 
        public EntityDictionaryBase(bool __isIgnoreItemNotExist)
        {
            this._isIgnoreItemNotExist = __isIgnoreItemNotExist;
            dictionay = new Dictionary<TK, TV>();
        }
        public virtual void Clear()
        {
            if (m_IsReadOnly)
            {
                throw new NotSupportedException("Collection is readonly.");
            }
            dictionay.Clear();
        }
 
        public virtual bool IsReadOnly
        {
            get { return m_IsReadOnly; }
        }
 
        #region IDictionary<TK,TV> 成员
 
        public virtual void Add(TK key, TV value)
        {
            if (m_IsReadOnly)
            {
                throw new NotSupportedException("Collection is readonly.");
            }
            dictionay.Add(key, value);
        }
 
        public virtual bool ContainsKey(TK key)
        {
            return dictionay.ContainsKey(key);
        }
 
        public virtual ICollection<TK> Keys
        {
            get { return dictionay.Keys; }
        }
 
        public virtual bool Remove(TK key)
        {
            return dictionay.Remove(key);
        }
 
        public virtual bool TryGetValue(TK key, out TV value)
        {
            return dictionay.TryGetValue(key, out value);
        }
 
        public virtual ICollection<TV> Values
        {
            get { return dictionay.Values; }
        }
 
        public virtual TV this[TK key]
        {
            get
            {
                return dictionay[key];
            }
            set
            {
                dictionay[key] = value;
            }
        }
 
        #endregion
 
        #region ICollection<KeyValuePair<TK,TV>> 成员
 
        public virtual void Add(KeyValuePair<TK, TV> item)
        {
            dictionay.Add(item.Key, item.Value);
        }
 
        public virtual bool Contains(KeyValuePair<TK, TV> item)
        {
            return dictionay.ContainsKey(item.Key) && dictionay.ContainsValue(item.Value);
        }
 
        public virtual void CopyTo(KeyValuePair<TK, TV>[] array, int arrayIndex)
        {
 
        }
 
        public virtual int Count
        {
            get { return dictionay.Count; }
        }
 
        public virtual bool Remove(KeyValuePair<TK, TV> item)
        {
            return false;
        }
 
        #endregion
 
        #region IEnumerable<KeyValuePair<TK,TV>> 成员
 
        public virtual IEnumerator<KeyValuePair<TK, TV>> GetEnumerator()
        {
            return dictionay.GetEnumerator();
        }
 
        #endregion
 
        #region IEnumerable 成员
 
        IEnumerator IEnumerable.GetEnumerator()
        {
            return dictionay.GetEnumerator();
        }
 
        #endregion
    }
}

这还只是一个集合基类,按照bbsmax的框架,我们需要为“全局模板变量”实体(TemplateVar)创建一个它专有的 “实体集合“类,不用觉得麻烦,它很简单,只需要继承刚才的 ”集合基类“就可以了。

using System;
using System.Collections.Generic;
using System.Text;
using MaxLabs.bbsMax.DataAccess;
using MaxLabs.bbsMax.Enums;
 
namespace MaxLabs.bbsMax.Entities
{
    /// <summary>
    /// 全局模板实体类变量集合
    /// </summary>
    public class TemplateVarDictionary : EntityDictionaryBase<string, TemplateVar>
    {
        public TemplateVarDictionary()
        {
        }
 
        /// <summary>
        /// 同实体类,根据数据库data对象,封装为集合。
        /// </summary>
        /// <param name="__readerWrap"></param>
        public TemplateVarDictionary(DataReaderWrap __readerWrap)
        {
            //while每次循环取一行数据,一行数据就是一个实体对象,封装之
            while (__readerWrap.Next)
            {
                //封装一行数据
                TemplateVar entity = new TemplateVar(__readerWrap);
                //加入集合
                base.Add(entity.Hash, entity);
            }
        }
 
        public TemplateVarDictionary(TemplateVarDictionary __collection)
        {
            if (__collection == null)
            {
                return;
            }
 
            foreach (var row in __collection)
            {
                this.Add(row.Key, row.Value);
            }
        }
 
        /// <summary>
        /// 嘿嘿,知道自己写集合类的好处了把,咱可以重写,多自由
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public override TemplateVar this[string key]
        {
            get
            {
                //如果根据key在集合内找不到指定的“全局模板变量”,则返回一行默认数据,
                //而不是让aspx报错,避免整个aspx页面会崩溃掉
                if (!base.ContainsKey(key))
                {
                    return new TemplateVar { Value = string.Format("给定的通用模板变量 {0} 不存在", key) };
                }
                return base[key];
            }
            set
            {
                base[key] = value;
            }
        }
 
    }
}

实体类 和 实体集合类 都已写好,下面写 抽象类(DAO)。
using MaxLabs.bbsMax.Entities;
//注意命名空间
namespace MaxLabs.bbsMax.DataAccess
{
    /// <summary>
    /// "全局模板变量"的数据库访问抽象类
    /// </summary>
    public abstract class TemplateVarDao : DaoBase<TemplateVarDao>
    {
        /// <summary>
        /// 查询
        /// </summary>
        /// <returns></returns>
        public abstract TemplateVarDictionary Select();
 
        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="__hash">模板变量的键</param>
        /// <param name="__value">模板变量的值</param>
        /// <returns></returns>
        public abstract int Insert(string __hash, string __value);
 
        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="__tvid">自增列</param>
        /// <param name="__hash"></param>
        /// <param name="__value"></param>
        /// <returns></returns>
        public abstract int Update(int __tvid, string __hash, string __value);
    }
}

按照bbsmax的框架,我们需要添加一个额外的 “全局模板变量”缓存类,不要觉得麻烦,其实结构很简单,就是一个静态的集合,一个访问器。
using MaxLabs.bbsMax.Entities;
 
namespace MaxLabs.bbsMax
{
    public class TemplateVarCachePool
    {
        //string key键/值集合
        static TemplateVarDictionary _vars;
 
        /// <summary>
        /// 缓存[集合]
        /// 一般从数据库数据库查询数据之后,存放到这里
        /// </summary>
        public static TemplateVarDictionary Vars
        {
            get { return _vars; }
            set { _vars = value; }
        }
 
        public void Clear()
        {
            if (_vars != null)
            {
                _vars.Clear();
            }
        }
 
    }
}

可以写逻辑类了
using MaxLabs.bbsMax.Entities;
 
namespace MaxLabs.bbsMax
{
    /// <summary>
    /// 全局模板变量[逻辑类]
    /// </summary>
    public class TemplateVarBO : BOBase<TemplateVarBO>
    {
        /// <summary>
        /// 查询
        /// </summary>
        /// <returns>可通过string key访问的集合</returns>
        public TemplateVarDictionary Select()
        {
            if (TemplateVarCachePool.Vars != null)
            {
                return TemplateVarCachePool.Vars;
            }
            TemplateVarCachePool.Vars = DataAccess.TemplateVarDao.Instance.Select();
            return TemplateVarCachePool.Vars;
        }
 
        public int Insert(string __hash, string __value)
        {
            return DataAccess.TemplateVarDao.Instance.Insert(__hash, __value);
        }
 
        public int Update(int __tvid, string __hash, string __value)
        {
            return DataAccess.TemplateVarDao.Instance.Update(__tvid, __hash, __value);
        }
 
    }
}

以上类都在[MaxLabs.bbsMax]层中。


实体,实体集合,数据访问抽象,缓存,逻辑,各类已经完成。下面实现“ 数据访问抽象类”的类
在[MaxLabs.bbsMax.DataAccess.SqlServer]层中,实现 [MaxLabs.bbsMax]层中 所有"数据访问抽象类"(DAO)。
using System.Data;
using MaxLabs.bbsMax.Entities;
 
namespace MaxLabs.bbsMax.DataAccess.SqlServer
{
    /// <summary>
    /// "全局模板变量"的数据库访问实现类
    /// </summary>
    public class TemplateVarDao : bbsMax.DataAccess.TemplateVarDao
    {
        /// <summary>
        /// 查询
        /// </summary>
        /// <returns></returns>
        public override TemplateVarDictionary Select()
        {
            using (SqlQuery query = new SqlQuery())
            {
                //SQL语句
                query.CommandText = "SELECT * FROM [bx_templatevars]";
                //SQL语句类型。
                query.CommandType = CommandType.Text;
                //查!
                using (XSqlDataReader reader = query.ExecuteReader())
                {
                    //new出自定义的“模板变量集合”
 
                    //封装方法1:
                    //将数据库reader对象丢过去,完成。
                    TemplateVarDictionary result = new TemplateVarDictionary(reader);
 
                    //封装方法2:
                    ////也可以这样
                    //while (reader.Next)
                    //{
                    //    TemplateVar entity = new TemplateVar(reader);
                    //    result.Add(entity.Hash, entity);
                    //}
 
                    return result;
                }
            }
        }
 
        public override int Insert(string __hash, string __value)
        {
            using (SqlQuery query = new SqlQuery())
            {
                string sql = "INSERT INTO [bx_templatevars] ([hash],[value]) VALUES (@hash,@value)";
                query.CreateParameter<string>("@hash", __hash, SqlDbType.NVarChar, 150);
                query.CreateParameter<string>("@value", __value, SqlDbType.NText);
                query.CommandText = sql;
                return query.ExecuteNonQuery();
            }
        }
 
        public override int Update(int __tvarid, string __hash, string __value)
        {
            using (SqlQuery query = new SqlQuery())
            {
                string sql = "UPDATE [bx_templatevars] SET [hash] = @hash, [value] = @value WHERE [tvarid] = @tvarid";
                query.CreateParameter<int>("@tvarid", __tvarid, SqlDbType.Int);
                query.CreateParameter<string>("@hash", __hash, SqlDbType.NVarChar, 150);
                query.CreateParameter<string>("@value", __value, SqlDbType.NText);
                query.CommandText = sql;
                return query.ExecuteNonQuery();
            }
        }
 
    }
}

添加一个  "抽象类实现类" 到 "抽象类(DAO)"  的实例化关系映射。
同样在[MaxLabs.bbsMax.DataAccess.SqlServer]层中:
\InternalCode\DataProvider 类下的

public T Create<T>() where T : DaoBase<T>
在这个“T Create<T>”方法的合适的位置("throw new Exception" 之上)添加如下代码:
if (typeof(T)==typeof(DataAccess.TemplateVarDao))
{
 return new TemplateVarDao() as T;
}

在页面基类添加变量访问器(第7步)。
在 [MaxLabs.bbsMax.Web]层的 _codes\_pagebase\BbsPageBase   页面基类下 ,添加如下代码
public TemplateVarDictionary Vars
{
 get { return TemplateVarBO.Instance.Select(); }     
}

修改论坛模板,添加如下代码:
<div id="">这是从数据库取到的vars["indexsay"]变量: $vars["indexsay"]</div>

posted @ 2012-02-09 20:50  Johnsonton's blog  阅读(228)  评论(0编辑  收藏  举报