zoukankan      html  css  js  c++  java
  • asp.net Forums 之配置,缓存,多数据访问

    在上一篇文章中,我谈到了asp.net Forums 之控件研究,这次我们来谈谈asp.net Forums 的配置、缓存和多数据访问。

    一、配置

    ANF的配置是通过ForumConfiguration类,ForumConfiguration类位于AspNetForums.Configuration命名空间下。

      

    代码
    #region VSS

    /*
    * $Header: /HiForums/Components/Configuration/ForumConfiguration.cs 1 05-10-26 15:04 Jacky $
    *
    * $History: ForumConfiguration.cs $
    *
    * ***************** Version 1 *****************
    * User: Jacky Date: 05-10-26 Time: 15:04
    * Created in $/HiForums/Components/Configuration
    *
    * ***************** Version 1 *****************
    * User: Jacky Date: 05-10-21 Time: 14:20
    * Created in $/HiForums/Components/Configuration
    *
    * ***************** Version 3 *****************
    * User: Jacky Date: 05-09-20 Time: 19:23
    * Updated in $/ASP.NET Forums/Components/Configuration
    *
    * ***************** Version 2 *****************
    * User: Jacky Date: 05-09-20 Time: 1:36
    * Updated in $/ASP.NET Forums/Components/Configuration
    */

    #endregion

    using System;
    using System.Collections;
    using System.Collections.Specialized;
    using System.IO;
    using System.Web;
    using System.Web.Caching;
    using System.Xml;
    using System.Configuration;
    using System.Xml.Serialization;
    using AspNetForums.Components;
    using AspNetForums.Enumerations;

    namespace AspNetForums.Configuration
    {
    // *********************************************************************
    // ForumConfiguration
    //
    /// <summary>
    /// 读取论坛配置信息,根据CS结构重构.
    /// by venjiang 2005/10/25
    /// </summary>
    ///
    // ***********************************************************************/
    public class ForumConfiguration
    {
    #region 成员字段
    public static readonly string CacheKey = "ForumsConfiguration";
    private Hashtable providers = new Hashtable();
    private Hashtable extensions = new Hashtable();
    private static readonly Cache cache = HttpRuntime.Cache;
    private string defaultProvider;
    private string defaultLanguage;
    private string forumFilesPath;
    private bool disableBackgroundThreads = false;
    private bool disableIndexing = false;
    private bool disableEmail = false;
    private string passwordEncodingFormat = "unicode";
    private int threadIntervalEmail = 15;
    private int threadIntervalStats = 15;
    //private SystemType systemType = SystemType.Self;
    private short smtpServerConnectionLimit = -1;
    private bool enableLatestVersionCheck = true;
    private string uploadFilesPath = "/Upload/";
    private XmlDocument XmlDoc = null;
    #endregion

    #region 构造器
    public ForumConfiguration(XmlDocument doc)
    {
    XmlDoc
    = doc;
    LoadValuesFromConfigurationXml();
    }
    #endregion

    #region 获取XML节点
    public XmlNode GetConfigSection(string nodePath)
    {
    return XmlDoc.SelectSingleNode(nodePath);
    }

    #endregion
    /*
    public static ForumConfiguration GetConfig()
    {
    return (ForumConfiguration) ConfigurationSettings.GetConfig("forums/forums");
    }
    */
    #region 获取配置信息实例
    public static ForumConfiguration GetConfig()
    {
    ForumConfiguration config
    = cache.Get(CacheKey) as ForumConfiguration;
    if(config == null)
    {
    string path;
    if(HttpContext.Current != null)
    path
    = HttpContext.Current.Server.MapPath("~/Forums.config");
    else
    path
    = Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + "Forums.config";

    XmlDocument doc
    = new XmlDocument();
    doc.Load(path);
    config
    = new ForumConfiguration(doc);
    cache.Insert(CacheKey,config,
    new CacheDependency(path),DateTime.MaxValue,TimeSpan.Zero,CacheItemPriority.AboveNormal,null);

    //cache.ReSetFactor(config.CacheFactor);
    }
    return config;

    }
    #endregion

    #region 加载配置文件设置
    internal void LoadValuesFromConfigurationXml()
    {
    XmlNode node
    = GetConfigSection("Forums/Core");
    XmlAttributeCollection attributeCollection
    = node.Attributes;

    // 默认数据提供者
    XmlAttribute att = attributeCollection["defaultProvider"];
    if(att != null)
    defaultProvider
    = att.Value;
    // 默认语言
    att = attributeCollection["defaultLanguage"];
    if(att != null)
    defaultLanguage
    =att.Value;
    else
    defaultLanguage
    = "zh-CN";
    // 论坛路径
    att = attributeCollection["forumFilesPath"];
    if(att != null)
    forumFilesPath
    = att.Value;
    else
    forumFilesPath
    = "/";
    // 禁用后台线程
    att = attributeCollection["disableThreading"];
    if(att != null)
    disableBackgroundThreads
    = bool.Parse(att.Value);
    else
    disableBackgroundThreads
    = false;
    // 禁止索引
    att = attributeCollection["disableIndexing"];
    if(att != null)
    disableIndexing
    = bool.Parse(att.Value);
    else
    disableIndexing
    = false;
    // 禁止邮件
    att = attributeCollection["disableEmail"];
    if(att != null)
    disableEmail
    = bool.Parse(att.Value);
    else
    disableEmail
    = false;
    // 密码加密格式
    att = attributeCollection["passwordEncodingFormat"];
    if(att != null)
    passwordEncodingFormat
    = att.Value;
    else
    passwordEncodingFormat
    = "unicode";
    // 后中统计状态
    att = attributeCollection["threadIntervalStats"];
    if(att != null)
    threadIntervalStats
    = int.Parse(att.Value);
    else
    threadIntervalStats
    = 15;
    // 邮件队列发送间隔
    att = attributeCollection["threadIntervalEmail"];
    if(att != null)
    threadIntervalEmail
    = int.Parse(att.Value);
    else
    threadIntervalEmail
    = 15;
    // SMTP服务器设置
    att = attributeCollection["smtpServerConnectionLimit"];
    if(att != null)
    smtpServerConnectionLimit
    = short.Parse(att.Value);
    else
    smtpServerConnectionLimit
    = -1;
    // 版本检查
    att = attributeCollection["enableLatestVersionCheck"];
    if(att != null)
    enableLatestVersionCheck
    = bool.Parse(att.Value);
    // 上传文件路径
    att = attributeCollection["uploadFilesPath"];
    if(att != null)
    uploadFilesPath
    = att.Value;

    // 读取子节点
    foreach (XmlNode child in node.ChildNodes)
    {
    if (child.Name == "providers")
    GetProviders(child, providers);

    if (child.Name == "extensionModules")
    GetProviders(child, extensions);

    }
    }

    #endregion

    #region 获取配置文件节点Provider
    internal void GetProviders(XmlNode node, Hashtable table)
    {
    foreach (XmlNode provider in node.ChildNodes)
    {
    switch (provider.Name)
    {
    case "add":
    table.Add(provider.Attributes[
    "name"].Value, new Provider(provider.Attributes));
    break;

    case "remove":
    table.Remove(provider.Attributes[
    "name"].Value);
    break;

    case "clear":
    table.Clear();
    break;

    }

    }

    }
    #endregion

    #region 公有属性
    // Properties
    //
    public string DefaultLanguage
    {
    get { return defaultLanguage; }
    }

    public string ForumFilesPath
    {
    get { return forumFilesPath; }
    }

    public string DefaultProvider
    {
    get { return defaultProvider; }
    }

    public Hashtable Providers
    {
    get { return providers; }
    }

    public Hashtable Extensions
    {
    get { return extensions; }
    }

    public bool IsBackgroundThreadingDisabled
    {
    get { return disableBackgroundThreads; }
    }

    public bool IsIndexingDisabled
    {
    get { return disableIndexing; }
    }

    public string PasswordEncodingFormat
    {
    get { return passwordEncodingFormat; }
    }

    public string UploadFilesPath
    {
    get { return uploadFilesPath; }
    }

    public bool IsEmailDisabled
    {
    get { return disableEmail; }
    }

    public int ThreadIntervalEmail
    {
    get { return threadIntervalEmail; }
    }

    public int ThreadIntervalStats
    {
    get { return threadIntervalStats; }
    }

    public short SmtpServerConnectionLimit
    {
    get { return smtpServerConnectionLimit; }
    }

    public bool EnableLatestVersionCheck
    {
    get { return enableLatestVersionCheck; }
    }
    #endregion
    }

    /// <summary>
    /// 数据提供者实体类
    /// </summary>
    public class Provider
    {
    #region 成员字段
    private string name;
    private string providerType;
    private ExtensionType extensionType;
    private NameValueCollection providerAttributes = new NameValueCollection();
    #endregion

    #region 构造器
    public Provider(XmlAttributeCollection attributes)
    {
    // Set the name of the provider
    //
    name = attributes["name"].Value;

    // Set the extension type
    //
    try
    {
    extensionType
    = (ExtensionType)Enum.Parse(typeof(ExtensionType), attributes["extensionType"].Value, true);
    }
    catch
    {
    // Occassionally get an exception on parsing the extensiontype, so set it to Unknown
    extensionType = ExtensionType.Unknown;
    }

    providerType
    = attributes["type"].Value;

    // Store all the attributes in the attributes bucket
    //
    foreach (XmlAttribute attribute in attributes)
    {
    if ((attribute.Name != "name") && (attribute.Name != "type"))
    providerAttributes.Add(attribute.Name, attribute.Value);

    }

    }
    #endregion

    #region 公有属性
    public string Name
    {
    get { return name; }
    }

    public string Type
    {
    get { return providerType; }
    }

    public ExtensionType ExtensionType
    {
    get { return extensionType; }
    }


    public NameValueCollection Attributes
    {
    get { return providerAttributes; }
    }

    #endregion
    }
    }
    // *********************************************************************
    // ForumsConfigurationHandler
    //
    /// <summary>
    /// Class used by ASP.NET Configuration to load ASP.NET Forums configuration.
    /// </summary>
    ///
    // ***********************************************************************/
    /*
    internal class ForumsConfigurationHandler : IConfigurationSectionHandler
    {
    public virtual object Create(Object parent, Object context, XmlNode node)
    {
    ForumConfiguration config = new ForumConfiguration();
    config.LoadValuesFromConfigurationXml(node);
    return config;
    }

    }
    */

    这个配置文件配置了ANF的默认数据提供者、默认语言、论坛路径、是滞禁用后台线程、是滞禁止索引、是否禁止邮件、密码加密格式、线程间隔状态、邮件队列发送间隔、SMTP服务器设置、版本检查
    上传文件路径、数据提供者、自定义HttpModule等。主要方法为GetConfig():

    代码
    public static ForumConfiguration GetConfig()
    {
    ForumConfiguration config
    = cache.Get(CacheKey) as ForumConfiguration;
    if(config == null)
    {
    string path;
    if(HttpContext.Current != null)
    path
    = HttpContext.Current.Server.MapPath("~/Forums.config");
    else
    path
    = Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + "Forums.config";

    XmlDocument doc
    = new XmlDocument();
    doc.Load(path);
    config
    = new ForumConfiguration(doc);
    cache.Insert(CacheKey,config,
    new CacheDependency(path),DateTime.MaxValue,TimeSpan.Zero,CacheItemPriority.AboveNormal,null);

    //cache.ReSetFactor(config.CacheFactor);
    }
    return config;

    }

    在此方法中,首先从Cache缓存中获取配置信息,如配置信息还未缓存,则读敢配置文件。配置文件位于网站根目录下的Forums.config文件。读取配置文件的内容后插入缓存中以便下次使用。
    Forums.config文件如下:

    代码
    <?xml version="1.0" encoding="utf-8" ?>
    <Forums>
    <Core defaultLanguage="zh-CN"
    forumFilesPath
    ="/"
    disableEmail
    ="false"
    disableIndexing
    ="true"
    disableThreading
    ="false"
    threadIntervalStats
    ="15"
    threadIntervalEmail
    ="15"
    smtpServerConnectionLimit
    ="-1"
    passwordEncodingFormat
    ="unicode"
    enableLatestVersionCheck
    ="false"
    uploadFilesPath
    ="/Upload/"
    defaultProvider
    ="SqlForumsProvider">
    <providers>
    <clear />
    <add name="LocalSqlForumsProvider" type="AspNetForums.Data.SqlDataProvider, AspNetForums.SqlDataProvider"
    connectionString
    ="server=.;database=Forums;uid=sa;pwd=" databaseOwner="dbo" />
    <add name="SqlForumsProvider" type="AspNetForums.Data.SqlDataProvider, AspNetForums.SqlDataProvider"
    connectionStringName
    = "SiteSqlServer" databaseOwnerStringName = "SiteSqlServerOwner" />
    <add name="SqlDataProviderNonDbo" type="AspNetForums.Data.SqlDataProviderNonDbo, AspNetForums.SqlDataProviderNonDbo"
    connectionStringName
    = "SiteSqlServer" databaseOwnerStringName = "SiteSqlServerOwner" />
    </providers>
    <extensionModules>
    <add name="PassportAuthentication" extensionType="Security" type="Telligent.CommunityServer.Security.PassportAuthentication, Telligent.CommunityServer.SecurityModules" />
    <add name="WindowsAuthentication" extensionType="Security" type="Telligent.CommunityServer.Security.WindowsAuthentication, Telligent.CommunityServer.SecurityModules"
    allowAutoUserRegistration
    ="true" adminWindowsGroup="Administrators" adminWindowsGroupIsSystemAdministrator="true" />
    <add name="FormsAuthentication" extensionType="Security" type="Telligent.CommunityServer.Security.FormsAuthentication, Telligent.CommunityServer.SecurityModules"
    allowAutoUserRegistration
    ="true" userEmailAddressCookie="CSUserEmailAddress" useEncryptedEmailAddressCookie="false" />
    </extensionModules>
    </Core>
    </Forums>

    二、缓存

    通过在类中添加private static readonly Cache cache = HttpRuntime.Cache;来实现。

    三、多数据访问

    ANF的数据访问基类是ForumsDataProvider类,ForumsDataProvider这个类位于AspNetForums.Components命名空间下。这是一个抽象类,你可以去实现你的SQL子类或其他子类。主要方法为两个实例化方法。
    实例化方法一:

    public static ForumsDataProvider Instance()
    {
    // 理论上应该出现不了null,但程序运行确实出现过.原因待查.
    if(_defaultInstance == null)
    CreateDefaultCommonProvider();
    return _defaultInstance;
    }

           
    在第一个实例化方法中,使用了单例设计模式,如果默认实例为空,则创建默认实例,方法如下:

    代码
    private static void CreateDefaultCommonProvider()
    {
    ForumConfiguration config
    = ForumConfiguration.GetConfig();
    Provider sqlForumsProvider
    = (Provider) config.Providers[config.DefaultProvider];
    _defaultInstance
    = DataProviders.CreateInstance(sqlForumsProvider) as ForumsDataProvider;
    }


    首先获取配置信息,通过配置信息中的默认数据提供者来创建默认实例。

    实例化方法二:

    代码
    public static ForumsDataProvider Instance (Provider dataProvider)
    {
    ForumsDataProvider fdp
    = cache.Get(dataProvider.Name) as ForumsDataProvider;
    if(fdp == null)
    {
    fdp
    = DataProviders.Invoke(dataProvider) as ForumsDataProvider;
    cache.Insert(dataProvider.Name,fdp,
    null,DateTime.MaxValue,TimeSpan.Zero,CacheItemPriority.AboveNormal,null);
    }
    return fdp;
    }


    在第二个实例化方法中,使用了缓存,通过给定的提供者,如果缓存中有,则直接调用。如果没有,则创建。创建后插入缓存以便下次使用。

    其它抽象方法为子类需要实现的真正的数据访问方法。

    欢迎大家指正。

  • 相关阅读:
    idea如何使用git关联远程仓库
    项目首次上传至git仓库步骤
    Eclipse 的 Java Web 项目环境搭建
    Postman
    Postman接口测试之POST、GET请求方法
    接口测试3A原则
    使用unittest和ddt进行数据驱动
    每天进步一点点006
    每天进步一点点005
    Selenium2+python自动化1-环境搭建(悠悠课程之路)
  • 原文地址:https://www.cnblogs.com/Jesong/p/1751524.html
Copyright © 2011-2022 走看看