# Summary

Class: | WireMock.Util.EnhancedFileSystemWatcher
Assembly: | WireMock.Net
File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Util\EnhancedFileSystemWatcher.cs
Covered lines: | 0
Uncovered lines: | 90
Coverable lines: | 90
Total lines: | 265
Line coverage: | 0%
Branch coverage: | 0%

# Metrics

Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage
--- | --- | --- | --- | ---
.ctor(...) | 2 | 0 | 0 | 0
.ctor(...) | 2 | 0 | 0 | 0
.ctor(...) | 2 | 0 | 0 | 0
OnChanged(...) | 2 | 2 | 0 | 0
OnCreated(...) | 2 | 2 | 0 | 0
OnDeleted(...) | 2 | 2 | 0 | 0
OnRenamed(...) | 2 | 2 | 0 | 0
InitializeMembers(...) | 1 | 0 | 0 | 0
HasAnotherFileEventOccuredRecently(...) | 3 | 4 | 0 | 0
OnChanged(...) | 2 | 2 | 0 | 0
OnCreated(...) | 2 | 2 | 0 | 0
OnDeleted(...) | 2 | 2 | 0 | 0
OnRenamed(...) | 2 | 2 | 0 | 0
Dispose() | 1 | 0 | 0 | 0

# File(s)

## C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Util\EnhancedFileSystemWatcher.cs

| # | Line |  | Line coverage
--- | --- | --- | --- | ---
|  | `1` |  | `using System;`
|  | `2` |  | `using System.Collections.Concurrent;`
|  | `3` |  | `using System.IO;`
|  | `4` |  | `using JetBrains.Annotations;`
|  | `5` |  | `using WireMock.Validation;`
|  | `6` |  | ``
|  | `7` |  | `namespace WireMock.Util`
|  | `8` |  | `{`
|  | `9` |  | `/// <summary>`
|  | `10` |  | `/// An EnhancedFileSystemWatcher, which can be used to suppress duplicate events that fire on a single change to the`
|  | `11` |  | `/// </summary>`
|  | `12` |  | `/// <seealso cref="System.IO.FileSystemWatcher" />`
|  | `13` |  | `/// <seealso cref="System.IDisposable" />`
|  | `14` |  | `public class EnhancedFileSystemWatcher : FileSystemWatcher, IDisposable`
|  | `15` |  | `{`
|  | `16` |  | `#region Private Members`
|  | `17` |  | `// Default Watch Interval in Milliseconds`
|  | `18` |  | `private const int DefaultWatchInterval = 100;`
|  | `19` |  | ``
|  | `20` |  | `// This Dictionary keeps the track of when an event occured last for a particular file`
|  | `21` |  | `private ConcurrentDictionary<string, DateTime> _lastFileEvent;`
|  | `22` |  | ``
|  | `23` |  | `// Watch Interval in Milliseconds`
|  | `24` |  | `private int _interval;`
|  | `25` |  | ``
|  | `26` |  | `// Timespan created when interval is set`
|  | `27` |  | `private TimeSpan _recentTimeSpan;`
|  | `28` |  | `#endregion`
|  | `29` |  | ``
|  | `30` |  | `#region Public Properties`
|  | `31` |  | `/// <summary>`
|  | `32` |  | `/// Interval, in milliseconds, within which events are considered "recent".`
|  | `33` |  | `/// </summary>`
|  | `34` |  | `[PublicAPI]`
|  | `35` |  | `public int Interval`
|  | `36` |  | `{`
| 0 | `37` |  | `get => _interval;`
|  | `38` |  | `set`
| 0 | `39` |  | `{`
| 0 | `40` |  | `_interval = value;`
|  | `41` |  | ``
|  | `42` |  | `// Set timespan based on the value passed`
| 0 | `43` |  | `_recentTimeSpan = new TimeSpan(0, 0, 0, 0, value);`
| 0 | `44` |  | `}`
|  | `45` |  | `}`
|  | `46` |  | ``
|  | `47` |  | `/// <summary>`
|  | `48` |  | `/// Allows user to set whether to filter recent events.`
|  | `49` |  | `/// If this is set a false, this class behaves like System.IO.FileSystemWatcher class.`
|  | `50` |  | `/// </summary>`
|  | `51` |  | `[PublicAPI]`
| 0 | `52` |  | `public bool FilterRecentEvents { get; set; }`
|  | `53` |  | `#endregion`
|  | `54` |  | ``
|  | `55` |  | `#region Constructors`
|  | `56` |  | `/// <summary>`
|  | `57` |  | `/// Initializes a new instance of the <see cref="EnhancedFileSystemWatcher"/> class.`
|  | `58` |  | `/// </summary>`
|  | `59` |  | `/// <param name="interval">The interval.</param>`
| 0 | `60` |  | `public EnhancedFileSystemWatcher(int interval = DefaultWatchInterval)`
| 0 | `61` |  | `{`
| 0 | `62` |  | `Check.Condition(interval, i => i >= 0, nameof(interval));`
|  | `63` |  | ``
| 0 | `64` |  | `InitializeMembers(interval);`
| 0 | `65` |  | `}`
|  | `66` |  | ``
|  | `67` |  | `/// <summary>`
|  | `68` |  | `/// Initializes a new instance of the <see cref="EnhancedFileSystemWatcher"/> class.`
|  | `69` |  | `/// </summary>`
|  | `70` |  | `/// <param name="path">The directory to monitor, in standard or Universal Naming Convention (UNC) notation.</par`
|  | `71` |  | `/// <param name="interval">The interval.</param>`
| 0 | `72` |  | `public EnhancedFileSystemWatcher([NotNull] string path, int interval = DefaultWatchInterval) : base(path)`
| 0 | `73` |  | `{`
| 0 | `74` |  | `Check.NotNullOrEmpty(path, nameof(path));`
| 0 | `75` |  | `Check.Condition(interval, i => i >= 0, nameof(interval));`
|  | `76` |  | ``
| 0 | `77` |  | `InitializeMembers(interval);`
| 0 | `78` |  | `}`
|  | `79` |  | ``
|  | `80` |  | `/// <summary>`
|  | `81` |  | `/// Initializes a new instance of the <see cref="EnhancedFileSystemWatcher"/> class.`
|  | `82` |  | `/// </summary>`
|  | `83` |  | `/// <param name="path">The directory to monitor, in standard or Universal Naming Convention (UNC) notation.</par`
|  | `84` |  | `/// <param name="filter">The type of files to watch. For example, "*.txt" watches for changes to all text files.`
|  | `85` |  | `/// <param name="interval">The interval.</param>`
| 0 | `86` |  | `public EnhancedFileSystemWatcher([NotNull] string path, [NotNull] string filter, int interval = DefaultWatchInte`
| 0 | `87` |  | `{`
| 0 | `88` |  | `Check.NotNullOrEmpty(path, nameof(path));`
| 0 | `89` |  | `Check.NotNullOrEmpty(filter, nameof(filter));`
| 0 | `90` |  | `Check.Condition(interval, i => i >= 0, nameof(interval));`
|  | `91` |  | ``
| 0 | `92` |  | `InitializeMembers(interval);`
| 0 | `93` |  | `}`
|  | `94` |  | `#endregion`
|  | `95` |  | ``
|  | `96` |  | `#region Events`
|  | `97` |  | `// These events hide the events from the base class.`
|  | `98` |  | `// We want to raise these events appropriately and we do not want the`
|  | `99` |  | `// users of this class subscribing to these events of the base class accidentally`
|  | `100` |  | ``
|  | `101` |  | `/// <summary>`
|  | `102` |  | `/// Occurs when a file or directory in the specified <see cref="P:System.IO.FileSystemWatcher.Path" /> is change`
|  | `103` |  | `/// </summary>`
|  | `104` |  | `public new event FileSystemEventHandler Changed;`
|  | `105` |  | ``
|  | `106` |  | `/// <summary>`
|  | `107` |  | `/// Occurs when a file or directory in the specified <see cref="P:System.IO.FileSystemWatcher.Path" /> is create`
|  | `108` |  | `/// </summary>`
|  | `109` |  | `public new event FileSystemEventHandler Created;`
|  | `110` |  | ``
|  | `111` |  | `/// <summary>`
|  | `112` |  | `/// Occurs when a file or directory in the specified <see cref="P:System.IO.FileSystemWatcher.Path" /> is delete`
|  | `113` |  | `/// </summary>`
|  | `114` |  | `public new event FileSystemEventHandler Deleted;`
|  | `115` |  | ``
|  | `116` |  | `/// <summary>`
|  | `117` |  | `/// Occurs when a file or directory in the specified <see cref="P:System.IO.FileSystemWatcher.Path" /> is rename`
|  | `118` |  | `/// </summary>`
|  | `119` |  | `public new event RenamedEventHandler Renamed;`
|  | `120` |  | `#endregion`
|  | `121` |  | ``
|  | `122` |  | `#region Protected Methods to raise the Events for this class`
|  | `123` |  | `/// <summary>`
|  | `124` |  | `/// Raises the <see cref="E:System.IO.FileSystemWatcher.Changed" /> event.`
|  | `125` |  | `/// </summary>`
|  | `126` |  | `/// <param name="e">A <see cref="T:System.IO.FileSystemEventArgs" /> that contains the event data.</param>`
|  | `127` |  | `protected new virtual void OnChanged(FileSystemEventArgs e)`
| 0 | `128` |  | `{`
| 0 | `129` |  | `Changed?.Invoke(this, e);`
| 0 | `130` |  | `}`
|  | `131` |  | ``
|  | `132` |  | `/// <summary>`
|  | `133` |  | `/// Raises the <see cref="E:System.IO.FileSystemWatcher.Created" /> event.`
|  | `134` |  | `/// </summary>`
|  | `135` |  | `/// <param name="e">A <see cref="T:System.IO.FileSystemEventArgs" /> that contains the event data.</param>`
|  | `136` |  | `protected new virtual void OnCreated(FileSystemEventArgs e)`
| 0 | `137` |  | `{`
| 0 | `138` |  | `Created?.Invoke(this, e);`
| 0 | `139` |  | `}`
|  | `140` |  | ``
|  | `141` |  | `/// <summary>`
|  | `142` |  | `/// Raises the <see cref="E:System.IO.FileSystemWatcher.Deleted" /> event.`
|  | `143` |  | `/// </summary>`
|  | `144` |  | `/// <param name="e">A <see cref="T:System.IO.FileSystemEventArgs" /> that contains the event data.</param>`
|  | `145` |  | `protected new virtual void OnDeleted(FileSystemEventArgs e)`
| 0 | `146` |  | `{`
| 0 | `147` |  | `Deleted?.Invoke(this, e);`
| 0 | `148` |  | `}`
|  | `149` |  | ``
|  | `150` |  | `/// <summary>`
|  | `151` |  | `/// Raises the <see cref="E:System.IO.FileSystemWatcher.Renamed" /> event.`
|  | `152` |  | `/// </summary>`
|  | `153` |  | `/// <param name="e">A <see cref="T:System.IO.RenamedEventArgs" /> that contains the event data.</param>`
|  | `154` |  | `protected new virtual void OnRenamed(RenamedEventArgs e)`
| 0 | `155` |  | `{`
| 0 | `156` |  | `Renamed?.Invoke(this, e);`
| 0 | `157` |  | `}`
|  | `158` |  | `#endregion`
|  | `159` |  | ``
|  | `160` |  | `#region Private Methods`
|  | `161` |  | `/// <summary>`
|  | `162` |  | `/// This Method Initializes the private members.`
|  | `163` |  | `/// Interval is set to its default value of 100 millisecond.`
|  | `164` |  | `/// FilterRecentEvents is set to true, _lastFileEvent dictionary is initialized.`
|  | `165` |  | `/// We subscribe to the base class events.`
|  | `166` |  | `/// </summary>`
|  | `167` |  | `private void InitializeMembers(int interval = 100)`
| 0 | `168` |  | `{`
| 0 | `169` |  | `Interval = interval;`
| 0 | `170` |  | `FilterRecentEvents = true;`
| 0 | `171` |  | `_lastFileEvent = new ConcurrentDictionary<string, DateTime>();`
|  | `172` |  | ``
| 0 | `173` |  | `base.Created += OnCreated;`
| 0 | `174` |  | `base.Changed += OnChanged;`
| 0 | `175` |  | `base.Deleted += OnDeleted;`
| 0 | `176` |  | `base.Renamed += OnRenamed;`
| 0 | `177` |  | `}`
|  | `178` |  | ``
|  | `179` |  | `/// <summary>`
|  | `180` |  | `/// This method searches the dictionary to find out when the last event occured`
|  | `181` |  | `/// for a particular file. If that event occured within the specified timespan`
|  | `182` |  | `/// it returns true, else false`
|  | `183` |  | `/// </summary>`
|  | `184` |  | `/// <param name="fileName">The filename to be checked</param>`
|  | `185` |  | `/// <returns>True if an event has occured within the specified interval, False otherwise</returns>`
|  | `186` |  | `private bool HasAnotherFileEventOccuredRecently(string fileName)`
| 0 | `187` |  | `{`
|  | `188` |  | `// Check dictionary only if user wants to filter recent events otherwise return value stays false.`
| 0 | `189` |  | `if (!FilterRecentEvents)`
| 0 | `190` |  | `{`
| 0 | `191` |  | `return false;`
|  | `192` |  | `}`
|  | `193` |  | ``
| 0 | `194` |  | `bool retVal = false;`
| 0 | `195` |  | `if (_lastFileEvent.ContainsKey(fileName))`
| 0 | `196` |  | `{`
|  | `197` |  | `// If dictionary contains the filename, check how much time has elapsed`
|  | `198` |  | `// since the last event occured. If the timespan is less that the`
|  | `199` |  | `// specified interval, set return value to true`
|  | `200` |  | `// and store current datetime in dictionary for this file`
| 0 | `201` |  | `DateTime lastEventTime = _lastFileEvent[fileName];`
| 0 | `202` |  | `DateTime currentTime = DateTime.Now;`
| 0 | `203` |  | `TimeSpan timeSinceLastEvent = currentTime - lastEventTime;`
| 0 | `204` |  | `retVal = timeSinceLastEvent < _recentTimeSpan;`
| 0 | `205` |  | `_lastFileEvent[fileName] = currentTime;`
| 0 | `206` |  | `}`
|  | `207` |  | `else`
| 0 | `208` |  | `{`
|  | `209` |  | `// If dictionary does not contain the filename,`
|  | `210` |  | `// no event has occured in past for this file, so set return value to false`
|  | `211` |  | `// and append filename along with current datetime to the dictionary`
| 0 | `212` |  | `_lastFileEvent.TryAdd(fileName, DateTime.Now);`
| 0 | `213` |  | `}`
|  | `214` |  | ``
| 0 | `215` |  | `return retVal;`
| 0 | `216` |  | `}`
|  | `217` |  | ``
|  | `218` |  | `#region FileSystemWatcher EventHandlers`
|  | `219` |  | `// Base class Event Handlers. Check if an event has occured recently and call method`
|  | `220` |  | `// to raise appropriate event only if no recent event is detected`
|  | `221` |  | `private void OnChanged(object sender, FileSystemEventArgs e)`
| 0 | `222` |  | `{`
| 0 | `223` |  | `if (!HasAnotherFileEventOccuredRecently(e.FullPath))`
| 0 | `224` |  | `{`
| 0 | `225` |  | `OnChanged(e);`
| 0 | `226` |  | `}`
| 0 | `227` |  | `}`
|  | `228` |  | ``
|  | `229` |  | `private void OnCreated(object sender, FileSystemEventArgs e)`
| 0 | `230` |  | `{`
| 0 | `231` |  | `if (!HasAnotherFileEventOccuredRecently(e.FullPath))`
| 0 | `232` |  | `{`
| 0 | `233` |  | `OnCreated(e);`
| 0 | `234` |  | `}`
| 0 | `235` |  | `}`
|  | `236` |  | ``
|  | `237` |  | `private void OnDeleted(object sender, FileSystemEventArgs e)`
| 0 | `238` |  | `{`
| 0 | `239` |  | `if (!HasAnotherFileEventOccuredRecently(e.FullPath))`
| 0 | `240` |  | `{`
| 0 | `241` |  | `OnDeleted(e);`
| 0 | `242` |  | `}`
| 0 | `243` |  | `}`
|  | `244` |  | ``
|  | `245` |  | `private void OnRenamed(object sender, RenamedEventArgs e)`
| 0 | `246` |  | `{`
| 0 | `247` |  | `if (!HasAnotherFileEventOccuredRecently(e.OldFullPath))`
| 0 | `248` |  | `{`
| 0 | `249` |  | `OnRenamed(e);`
| 0 | `250` |  | `}`
| 0 | `251` |  | `}`
|  | `252` |  | `#endregion`
|  | `253` |  | `#endregion`
|  | `254` |  | ``
|  | `255` |  | `#region IDisposable Members`
|  | `256` |  | `/// <summary>`
|  | `257` |  | `/// Releases all resources used by the <see cref="T:System.ComponentModel.Component" />.`
|  | `258` |  | `/// </summary>`
|  | `259` |  | `public new void Dispose()`
| 0 | `260` |  | `{`
| 0 | `261` |  | `base.Dispose();`
| 0 | `262` |  | `}`
|  | `263` |  | `#endregion`
|  | `264` |  | `}`
|  | `265` |  | `}`

# Methods/Properties

Interval()
Interval(System.Int32)
FilterRecentEvents()
FilterRecentEvents(System.Boolean)
.ctor(System.Int32)
.ctor(System.String,System.Int32)
.ctor(System.String,System.String,System.Int32)
OnChanged(System.IO.FileSystemEventArgs)
OnCreated(System.IO.FileSystemEventArgs)
OnDeleted(System.IO.FileSystemEventArgs)
OnRenamed(System.IO.RenamedEventArgs)
InitializeMembers(System.Int32)
HasAnotherFileEventOccuredRecently(System.String)
OnChanged(System.Object,System.IO.FileSystemEventArgs)
OnCreated(System.Object,System.IO.FileSystemEventArgs)
OnDeleted(System.Object,System.IO.FileSystemEventArgs)
OnRenamed(System.Object,System.IO.RenamedEventArgs)
Dispose()