如何分割web.config

本文介绍了一种将大型Web应用程序中的Web.Config配置文件分割成多个小文件的方法,以提高维护性和可读性。通过创建特定功能的配置文件,并使用序列化和反序列化技术来同步配置,同时利用文件监视器自动更新配置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

      做B/S的朋友对于web.config这个配置文件再熟悉不过了,很多配置的内容都需要在它里面实现,例如最觉的包含以下几个情况:
         1:数据库连接串;
         2:url重写时的一些配置;
         3:日志组件的配置;
         4:诸多常量的配置;
         5...
      这样做本是没有错的,只是我觉的可以改进下,因为这样会使web.config文件日益庞大,以后找一个配置特别难,其实我们可以把有些配置从传统的web.config文件中分割出去。正好同事做了这块,觉的不错,特整理了一下思路。
  

      第一步:按功能创建不同的配置文件,例如我这里创建了一个配置文件SimpleFileDemoConfig.config,里面为了测试只包含一个配置节sUserName。

<?xml version="1.0" encoding="UTF-8"?>
<SimpleFileDemoConfig>        
    
<sUserName>aaa</sUserName>
</SimpleFileDemoConfig>

  

     第二步:写对应的配置文件实体类,SimpleFileDemoConfig.cs,,里面还包含一个不需要序列化的属性,即配置文件的名称。

                注意点:

                         1:类里面的属性和配置文件的名称完全相同。方便序列化和反序列化。

                          2:并且标明此类可序列化。

                          3:类名保持和配置文件的名称相同,即SimpleFileDemoConfig。如果不是会在反序列化时报错哟。 

ExpandedBlockStart.gifContractedBlock.gif/**//// <summary>
    
/// 第一步:建立配置文件的实体类.只包含属性和私有字段.不提供任何方法.
    
/// 包含两部分:1.需要保存到配置文件中的属性.  2.不需要序列化的子文件路径.
    
/// 配置文件和类属性名相同
    
/// </summary>

    [Serializable]
    
public class SimpleFileDemoConfig
ExpandedBlockStart.gifContractedBlock.gif    
{
ContractedSubBlock.gifExpandedSubBlockStart.gif        
需要序列化的配置文件属性#region 需要序列化的配置文件属性
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 用户名
        
/// </summary>

        public string sUserName
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
get;
            
set;
        }

        
#endregion


ContractedSubBlock.gifExpandedSubBlockStart.gif        
相对于Config文件夹的子文件路径,不需要序列化.#region 相对于Config文件夹的子文件路径,不需要序列化.
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 相对于Config文件夹的子文件路径,不需要序列化.
        
/// </summary>

        [NonSerialized()]
        
private static string m_SubFilePath = @"SimpleFileDemoConfig.config";
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 子文件路径(排除config文件夹路径后的部分)
        
/// </summary>

        public static string SubFilePath
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get return m_SubFilePath; }
ExpandedSubBlockStart.gifContractedSubBlock.gif            
set { m_SubFilePath = value; }
        }

        
#endregion

        
    }

     第三步:先设计一些工具类。
             1:配置文件的序列化和反序列化的工具类SerializationHelper.cs,这主要包含两个方法,序列化Save和反序列化Load,接受的参数都是对象类型和配置文件路径。
             
ContractedBlock.gifExpandedBlockStart.gifCode
ExpandedBlockStart.gifContractedBlock.gif/**//// <summary>
        
/// 反序列化
        
/// </summary>
        
/// <param name="type">对象类型</param>
        
/// <param name="filename">文件路径</param>
        
/// <returns></returns>

        public static object Load(Type type, string filename)
ExpandedBlockStart.gifContractedBlock.gif        
{
            FileStream fs 
= null;
            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
// open the stream
                fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                XmlSerializer serializer 
= new XmlSerializer(type);
                
return serializer.Deserialize(fs);
            }

            
catch (Exception ex)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
throw ex;
            }

            
finally
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
if (fs != null)
                    fs.Close();
            }

        }



ExpandedBlockStart.gifContractedBlock.gif        
/**//// <summary>
        
/// 序列化
        
/// </summary>
        
/// <param name="obj">对象</param>
        
/// <param name="filename">文件路径</param>

        public static void Save(object obj, string filename)
ExpandedBlockStart.gifContractedBlock.gif        
{
            FileStream fs 
= null;
            
// serialize it
            try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                fs 
= new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
                XmlSerializer serializer 
= new XmlSerializer(obj.GetType());
                serializer.Serialize(fs, obj);
            }

            
catch (Exception ex)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
throw ex;
            }

            
finally
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
if (fs != null)
                    fs.Close();
            }


        }
        

            2:文件监视工具类FileWatchHelper,主要参考了log4net的部分源码。它会监控配置文件的变化,包含内容变化,最后修改时间等。一旦发现配置文件有变则调用相应方法更新配置文件类的实例。            

ContractedBlock.gifExpandedBlockStart.gifCode
ExpandedBlockStart.gifContractedBlock.gif/**//// <summary>
        
/// 一个监视配置文件的计数器
        
/// </summary>

        private Timer m_timer;

ExpandedBlockStart.gifContractedBlock.gif        
/**//// <summary>
        
/// 监视器的时间间隔
        
/// </summary>

        private const int TimeoutMillis = 500;

ContractedBlock.gifExpandedBlockStart.gif        
Constructed Function#region Constructed Function
        
private FileWatchHelper(FileUpdate updateProcess, string filePath, string fileName)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
// 创建 FileSystemWatcher 及相关属性.
            FileSystemWatcher watcher = new FileSystemWatcher();
            
//监视的路径
            filePath =filePath .Substring (0,filePath.LastIndexOf("\\")+1);
            watcher.Path 
= filePath;
            
//监视时所包含的文件名
            watcher.Filter = fileName;
            watcher.IncludeSubdirectories 
= true;

            
//过滤条件
            watcher.NotifyFilter = NotifyFilters.CreationTime | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;

            
// Add event handlers. OnChanged will do for all event handlers that fire a FileSystemEventArgs
            watcher.Changed += new FileSystemEventHandler(ConfigureAndWatchHandler_OnChanged);

            
// 启动监视
            watcher.EnableRaisingEvents = true;

            
// Create the timer that will be used to deliver events. Set as disabled
            m_timer = new Timer(new TimerCallback(updateProcess), filePath, Timeout.Infinite, Timeout.Infinite);

        }


        
private FileWatchHelper(FileUpdate updateProcess, string filePath)
            : 
this(updateProcess, filePath, "")
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
        }


        
#endregion


ContractedBlock.gifExpandedBlockStart.gif        
Method#region  Method 

ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// Event handler used by <see cref="ConfigureAndWatchHandler"/>.
        
/// </summary>
        
/// <param name="source">The <see cref="FileSystemWatcher"/> firing the event.</param>
        
/// <param name="e">The argument indicates the file that caused the event to be fired.</param>
        
/// <remarks>
        
/// <para>
        
/// This handler reloads the configuration from the file when the event is fired.
        
/// </para>
        
/// </remarks>

        private void ConfigureAndWatchHandler_OnChanged(object source, FileSystemEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            m_timer.Change(TimeoutMillis, Timeout.Infinite);
        }


        
#endregion


ContractedBlock.gifExpandedBlockStart.gif        
Static Method#region  Static Method 

ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 开始监视
        
/// </summary>
        
/// <param name="updateProcess">委托</param>
        
/// <param name="filePath">监视的文件路径</param>
        
/// <param name="fileName">监视的文件名称</param>

        static public void StartWatching(FileUpdate updateProcess, string filePath)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
//new FileWatchHelper(updateProcess, filePath, fileName);
            new FileWatchHelper(updateProcess, filePath);
        }


        
#endregion

   

      第四步:建立一个CustomWebConfig类,它统一管理所有自定义的配置类,它主要包含一个启动方法,它的功能包含两个方面:

             1:是将自定义的配置文件反序列化成实例变量供开发员调用。

             2:对配置文件进行监视,一旦配置文件发生变化,同时更新实例变量的内容,达到信息同步。

ContractedBlock.gifExpandedBlockStart.gifCode
ExpandedBlockStart.gifContractedBlock.gif/**//// <summary>
        
/// 启动配置类
        
/// </summary>

        public static void OnStart(string configFilePath)
ExpandedBlockStart.gifContractedBlock.gif        
{
ContractedSubBlock.gifExpandedSubBlockStart.gif            
实现配置文件独立#region  实现配置文件独立  
ExpandedSubBlockStart.gifContractedSubBlock.gif            
/**//*
             * 将配置文件按照配置类切割,放置在独立的文件夹中.
             * 监控文件变化.任何一个文件发生内容改变,则更新配置类
             
*/


            
//设置监控独立配置文件所在文件夹.开发环境会监控
            string filePath = string.Empty;

            filePath 
= AppDomain.CurrentDomain.BaseDirectory;
           
            filePath 
+= configFilePath;


            
//文件改变时执行的方法委托.需要将每个配置文件的更新方法添加到委托中
            FileUpdate fileUpdate = new FileUpdate(CustomWebConfig.SimpleFileDemoConfigOnUpdate);
           
//第四步:为添加SimpleFileDemoConfig类添加更新函数.

            
//第一次启动需要执行委托方法更新配置类
            fileUpdate(filePath);

            
//启动文件监视
            FileWatchHelper.StartWatching(fileUpdate, filePath);

            
#endregion

        }

ContractedBlock.gifExpandedBlockStart.gif        
第二步:为SimpleFileDemoConfig类添加入口#region 第二步:为SimpleFileDemoConfig类添加入口
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 属性对应的私有变量
        
/// </summary>

        private static SimpleFileDemoConfig m_SimpleFileDemoConfig = new SimpleFileDemoConfig();
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 属性访问器.通过WebConfig.SimpleFileDemoConfig可以访问此类.
        
/// </summary>

        public static SimpleFileDemoConfig SimpleFileDemoConfig
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get return m_SimpleFileDemoConfig; }
ExpandedSubBlockStart.gifContractedSubBlock.gif            
set { m_SimpleFileDemoConfig = value; }
        }

        
#endregion


ContractedBlock.gifExpandedBlockStart.gif        
第三步:为SimpleFileDemoConfig类添加更新函数#region 第三步:为SimpleFileDemoConfig类添加更新函数
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 更新函数
        
/// </summary>
        
/// <param name="status"></param>

        public static void SimpleFileDemoConfigOnUpdate(object status)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
lock (CustomWebConfig.SimpleFileDemoConfig)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
try
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    
string filePath = Convert.ToString(status)+SimpleFileDemoConfig .SubFilePath ;
                    m_SimpleFileDemoConfig 
= SerializationHelper.Load(typeof(SimpleFileDemoConfig), filePath) as

SimpleFileDemoConfig;
                }

                
catch (Exception ex)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    
throw ex;
                }

            }

        }

        
#endregion

      第五步:找一个合适的地方启动自定义的配置类应用,可能选择在Global中的Application_Start中添加CustomWebConfig.OnStart("");

      第六步:客户端调用。  

string sUserName= CustomWebConfig.SimpleFileDemoConfig.sUserName ;

 

      总结:上面的六步就实现了web.config文件分割,简单实用.以后如果想增加一个节点的内容只要做如下两步就行:
            1:修改配置文件SimpleFileDemoConfig,例如增加一个节点<sPS>aaa</sPS>。
            2:为SimpleFileDemoConfig.cs类增加一个属性,属性名称和配置文件中增加的节点名称相同即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值