using System; using System.Collections.Generic; using System.IO; using System.Linq; namespace ArchestrAServices.Common; public sealed class ConfigFileWatcher : IDisposable { private static readonly ConfigFileWatcher theInstance = new ConfigFileWatcher(); private readonly List eventHandlers = new List(); private bool disposed; private FileSystemWatcher watcher; private ConfigFileWatcher() { string directoryName = Path.GetDirectoryName(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile); string fileName = Path.GetFileName(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile); if (string.IsNullOrWhiteSpace(directoryName) || string.IsNullOrWhiteSpace(fileName)) { throw new ArgumentException("Invalid configuration file path."); } watcher = new FileSystemWatcher(directoryName, fileName); AppDomain.CurrentDomain.ProcessExit += delegate { Dispose(); }; } public static void AddHandler(FileSystemEventHandler eventHandler) { theInstance.RegisterHandler(eventHandler); } public static void RemoveHandler(FileSystemEventHandler eventHandler) { theInstance.UnRegisterHandler(eventHandler); } public void Dispose() { Dispose(disposing: true); } private void RegisterHandler(FileSystemEventHandler eventHandler) { if (watcher != null) { watcher.Changed += eventHandler; eventHandlers.Add(eventHandler); watcher.EnableRaisingEvents = true; } } private void UnRegisterHandler(FileSystemEventHandler eventHandler) { if (watcher != null) { watcher.Changed -= eventHandler; eventHandlers.Remove(eventHandler); if (!eventHandlers.Any()) { watcher.EnableRaisingEvents = false; } } } private void Dispose(bool disposing) { if (disposed) { return; } if (disposing && watcher != null) { foreach (FileSystemEventHandler eventHandler in eventHandlers) { watcher.Changed -= eventHandler; } watcher.EnableRaisingEvents = false; watcher.Dispose(); watcher = null; eventHandlers.Clear(); } disposed = true; } }