There are 7 private functions
Function: ConfigurationExists()
The ConfigurationExists function, just checks if the file exists or not
/// <summary> /// Check if the Confiuration File exists /// </summary> /// <returns></returns> private bool ConfigurationExists() { _log.Debug("<--> ConfigurationExists"); return File.Exists(_configurationPath + _configurationFile); }
Function: CreateConfiguration()
Within the Function it is first checked if the Configuration has been set, if not the Function “SetDefaultValues()” creates a set of standard values for the properties. Next we check if the Configuration exists, this is done because saving the normal configuration and creating a standard configuration is done through the same function.
We iterate through the dictionary and write all the key-value Items into the configuration file.
/// <summary> /// Create the Standard configuration with the property values /// </summary> private void CreateConfiguration() { _log.Debug("--> CreateStandardConfiguration"); if (!ConfigurationSet) SetDefautlValues(); if (!ConfigurationExists()) Directory.CreateDirectory(_configurationPath); using (FileStream fs = new FileStream(_configurationPath + _configurationFile, FileMode.OpenOrCreate, FileAccess.Write)) { using (StreamWriter sw = new StreamWriter(fs)) { foreach (KeyValuePair<string, object> configItem in ConfigurationItems) { sw.WriteLine(configItem.Key + "=" + configItem.Value); } } } _log.Debug("<-- CreateStandardConfiguration: Created standard configuration and file: {0}", _configurationPath + _configurationFile); }
Function: SetDefaultValues()
This function just creates a set of default values, if no file has been found.
/// <summary> /// Set Default Values for the Configuration /// </summary> private void SetDefautlValues() { _log.Debug("--> SetDefaultValues"); LocalIPAddress = "10.254.0.101"; LocalPort = "0"; RemoteIPAddress = "10.254.0.133"; RemotePort = "43238"; TCP = false; UDP = false; Multicast = true; GzipCompression = false; ReceiveBufferSize = "8192"; MaxSegmentSize = "200"; SocketBufferSize = "8388608"; MulticastSendTimeoutInMS = "500"; DateMatchGroup = @"(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3})"; TextAfterDateMatch = @"(.*)"; TextBeforeProviderMatchGroup = @"CallList from"; ProviderMatchGroup = @"(.*)"; TextBeforeXMLCallListMatchGroup = @"\/MTP received. New Revision \(\d{1,9}\):"; CallListMatchGroup = @"(.*)"; FullRegex = DateMatchGroup + TextAfterDateMatch + TextBeforeProviderMatchGroup + ProviderMatchGroup + TextBeforeXMLCallListMatchGroup + CallListMatchGroup; ExtractionFolder = @"C:\Temp\"; ExtractionFileName = @"extraction.log"; ConfigurationSet = true; PropertiesToDictionary(); _log.Debug("<-- SetDefaultValues"); }
Function: ReadConfiguration()
The ReadConfiguration function opens a Filestream to the configuration file and reads all key-value pairs, line by line, every line is split and given to the “UpdateDictionaryValue”-Function.
After all Dictionary Entries are updated, the Dictionary is transfered to the Singleton object, so it can be accessed by other parts of the program.
/// <summary> /// Read Configuration from Configuration File /// </summary> private void ReadConfiguration() { _log.Debug("--> ReadConfiguration"); using (FileStream fileStream = new FileStream(_configurationPath + _configurationFile, FileMode.Open, FileAccess.Read)) { using (StreamReader streamreader = new StreamReader(fileStream)) { string configurationLine; while (!streamreader.EndOfStream) { configurationLine = streamreader.ReadLine(); configurationLine = configurationLine.Trim(); //=== Equals a Topic and can be ignored if (!configurationLine.Contains("===")) { string[] configItem = configurationLine.Split('='); UpdateDictionaryValue(configItem); } } } } ConfigurationSet = true; ConfigurationItems[nameof(ConfigurationSet)] = true; DictionaryToProperties(); _log.Debug("<-- ReadConfiguration"); }
Function: UpdateDictionaryValue(configItem)
The Function checks if an configuration item is within the dictionary and if it finds it, updates the value for this particular item.
/// <summary> /// Transfers the read configuration Item to the Property, so it can be accessed from outside /// </summary> /// <param name="configItem">String Array with Propertyname and Propertyvalue</param> private void UpdateDictionaryValue(string[] configItem) { _log.Debug("--> TransformConfigurationItemToPropertyViaReflection: Configuration Item: {0}, Configuration Value: {1}", configItem[0], configItem[1]); if (ConfigurationItems.ContainsKey(configItem[0])) ConfigurationItems[configItem[0]] = configItem[1]; else _log.Error("### Configuration Item with Key: {0} and Value: {1} couldn't be found", configItem[0], configItem[1]); _log.Trace("<-- TransformConfigurationItemToPropertyViaReflection"); }
Now to the last 2 private functions were all the magic happens, actually the refer to a new class, but we go there in just a minute.
Funcion: PropertiesToDictionary()
This function takes itself (this) and gets a Dictionary via a static class and reflections with all the properties as key-value pairs
/// <summary> /// Uses Reflection to get a dictionary of the properties /// </summary> private void PropertiesToDictionary() { _log.Debug("--> GenerateDictionaryFromProperties"); ConfigurationItems = (Dictionary<string, object>)ObjectExtensions.ObjectToDictionary(this); _log.Debug("### Properties found {0}", ConfigurationItems.Count); _log.Debug("<-- GenerateDictionaryFromProperties"); }
Function: DictionaryToProperties()
This function transfers all the Key-Value Pairs of the dictionary to the singleton for external excess.
/// <summary> /// Transforms the Dictionary to the Singleton Properties /// </summary> private void DictionaryToProperties() { _log.Debug("--> DictionaryToProperties"); Configuration = ObjectExtensions.ObjectFromDictionary<ConfigurationHelper>(ConfigurationItems); _log.Debug("<-- DictionaryToProperties"); }