.net dynamically refresh app.config

前端 未结 10 794
闹比i
闹比i 2020-12-02 23:28

How do I dynamically reload the app.config in a .net Windows application? I need to turn logging on and off dynamically and not just based upon the value at application sta

10条回答
  •  感动是毒
    2020-12-02 23:52

    I wrote this implementation to change the log level at runtime and persist the new treshold back to the app.config (actually the Application.exe.config).

    The interface:

    internal interface ILoggingConfiguration
    {
      void SetLogLevel(string level);
    
      string GetLogLevel();
    }
    

    The implementation:

    internal sealed class LoggingConfigurationImpl : ILoggingConfiguration
    {
      #region Members
    
      private static readonly ILog _logger = 
        ObjectManager.Common.Logger.GetLogger();
      private const string DEFAULT_NAME_SPACE = "Default.Name.Space";
    
      #endregion
    
      #region Implementation of ILoggingConfiguration
    
      public void SetLogLevel(string level)
      {
        Level threshold = Log4NetUtils.ConvertToLevel(level);
        ILoggerRepository[] repositories = LogManager.GetAllRepositories();
    
        foreach (ILoggerRepository repository in repositories)
        {
          try
          {
            SetLogLevelOnRepository(repository, threshold);
          }
          catch (Exception ex)
          {
            _logger.ErrorFormat("Exception while changing log-level: {0}", ex);
          }
        }
        PersistLogLevel(level);
      }
    
      public string GetLogLevel()
      {
        ILoggerRepository repository = LogManager.GetRepository();
        Hierarchy hierarchy = (Hierarchy) repository;
        ILogger logger = hierarchy.GetLogger(DEFAULT_NAME_SPACE);
        return ((Logger) logger).Level.DisplayName;
      }
    
      private void SetLogLevelOnRepository(ILoggerRepository repository,
                                           Level threshold)
      {
        repository.Threshold = threshold;
        Hierarchy hierarchy = (Hierarchy)repository;
        ILogger[] loggers = hierarchy.GetCurrentLoggers();
        foreach (ILogger logger in loggers)
        {
          try
          {
            SetLogLevelOnLogger(threshold, logger);
          }
          catch (Exception ex)
          {
            _logger.ErrorFormat("Exception while changing log-level for 
                logger: {0}{1}{2}", logger, Environment.NewLine, ex);
          }
        }
      }
    
      private void SetLogLevelOnLogger(Level threshold, ILogger logger)
      {
        ((Logger)logger).Level = threshold;
      }
    
      private void PersistLogLevel(string level)
      {
        XmlDocument config = new XmlDocument();
        config.Load(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
        string xpath =
          String.Format("configuration/log4net/logger[@name='{0}']/level",
            DEFAULT_NAME_SPACE);
        XmlNode rootLoggerNode = config.SelectSingleNode(xpath);
    
        try
        {
          rootLoggerNode.Attributes["value"].Value = level;
          config.Save(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
    
          ConfigurationManager.RefreshSection("log4net");
        }
        catch(Exception ex)
        {
          _logger.ErrorFormat("error while persisting new log-level: {0}", ex);
        }
      }
    
      #endregion
    }
    

    The helper class Log4NetUtils:

    public sealed class Log4NetUtils
    {
      private static readonly ILoggerRepository _loggerRepository =
         LoggerManager.GetAllRepositories().First();
    
      public static Level ConvertToLevel(string level)
      {
        return _loggerRepository.LevelMap[level];
      }
    }
    

    The XAML code:

    
      
      
      
      
    
    
    

提交回复
热议问题