diff --git a/GBase/DataHandling/Cache/XmlDataHandlerCache.cs b/GBase/DataHandling/Cache/XmlDataHandlerCache.cs
new file mode 100644
index 0000000..ce3b125
--- /dev/null
+++ b/GBase/DataHandling/Cache/XmlDataHandlerCache.cs
@@ -0,0 +1,132 @@
+// Author: Gockner, Simon
+// Created: 2020-02-12
+// Copyright(c) 2020 SimonG. All Rights Reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using GBase.Interfaces.DataHandling.Cache;
+using GBase.Interfaces.DataHandling.Xml;
+using GBase.Interfaces.DataHandling.Xml.Cache;
+using GBase.Interfaces.DataHandling.Xml.Cache.Factories;
+
+namespace GBase.DataHandling.Cache
+{
+ ///
+ /// An interface for the
+ ///
+ public class XmlDataHandlerCache : IXmlDataHandlerCache
+ {
+ private readonly IXmlDataReader _xmlDataReader;
+ private readonly IXmlDataHandlerCacheEntryFactory _xmlDataHandlerCacheEntryFactory;
+ private readonly IXmlDataHandlerCachePropertyEntryFactory _xmlDataHandlerCachePropertyEntryFactory;
+
+ private readonly List _cache;
+
+ ///
+ /// An interface for the
+ ///
+ /// The
+ /// A factory for the
+ /// A factory for the
+ public XmlDataHandlerCache(IXmlDataReader xmlDataReader,
+ IXmlDataHandlerCacheEntryFactory xmlDataHandlerCacheEntryFactory,
+ IXmlDataHandlerCachePropertyEntryFactory xmlDataHandlerCachePropertyEntryFactory)
+ {
+ _xmlDataReader = xmlDataReader;
+ _xmlDataHandlerCacheEntryFactory = xmlDataHandlerCacheEntryFactory;
+ _xmlDataHandlerCachePropertyEntryFactory = xmlDataHandlerCachePropertyEntryFactory;
+
+ _cache = new List();
+ }
+
+ ///
+ /// Set the value for the given property
+ ///
+ /// The that implements the property
+ /// The of the property
+ /// The name of the property
+ /// The value to set
+ /// If true an existing value is overwritten, if false an additional value is added
+ /// A to await
+ public async Task SetValue(string propertyName, TProperty value, bool overwrite) //TODO: async?
+ {
+ IXmlDataHandlerCacheEntry entry = _cache.FirstOrDefault(e => e.Type == typeof(T));
+ if (entry != null) //entry exists
+ {
+ IDataHandlerCachePropertyEntry property = entry.Properties.FirstOrDefault(p => p.PropertyName.Equals(propertyName));
+ if (property != null) //property entry exists
+ {
+ if (overwrite)
+ property.Values[0] = value; //if overwrite is true, overwrite first value
+ else if (property.Values.Any(v => v.Equals(value))) //same value already exists for this property
+ {
+ object sameValue = property.Values.First(v => v.Equals(value));
+ if (property.Values.IndexOf(sameValue) == 0) //if it is the first item already, do nothing
+ return;
+
+ property.Values.Remove(sameValue); //remove it
+ property.Values.Insert(0, sameValue); //insert it at the first position
+ }
+ else //overwrite is false and no equal value exists
+ property.Values.Insert(0, value); //insert value at the first position
+ }
+ else //property entry doesn't exist
+ entry.Properties.Add(_xmlDataHandlerCachePropertyEntryFactory.Create(propertyName, value)); //create new property entry
+ }
+ else //entry doesn't exist
+ _cache.Add(_xmlDataHandlerCacheEntryFactory.Create(typeof(T), propertyName, value)); //create new entry
+ }
+
+ ///
+ /// Remove the value for the given property
+ ///
+ /// The of the property
+ /// The of the property
+ /// The name of the property
+ /// The value to set
+ /// A to await
+ public async Task TryRemoveValue(string propertyName, TProperty value) //TODO: async?
+ {
+ IXmlDataHandlerCacheEntry entry = _cache.FirstOrDefault(e => e.Type == typeof(T));
+ IDataHandlerCachePropertyEntry property = entry?.Properties.FirstOrDefault(p => p.PropertyName.Equals(propertyName));
+ object valueToRemove = property?.Values.FirstOrDefault(v => v.Equals(value));
+ if (valueToRemove == null)
+ return;
+
+ property.Values.Remove(valueToRemove);
+ }
+
+ ///
+ /// Try to get values from the cache for the given property
+ ///
+ /// The that implements the property
+ /// The of the property
+ /// The name of the property
+ /// An with all the values for the property
+ public async Task> TryGetValues(string propertyName)
+ {
+ IXmlDataHandlerCacheEntry entry = _cache.FirstOrDefault(e => e.Type == typeof(T));
+ IDataHandlerCachePropertyEntry property = entry?.Properties.FirstOrDefault(p => p.PropertyName.Equals(propertyName));
+ if (property == null)
+ return null;
+
+ if (!property.IsInitialized) //initialize property by reading the values from the xml
+ {
+ List values = (await _xmlDataReader.Read(propertyName))?.ToList();
+ if (values != null)
+ {
+ foreach (TProperty value in values.Where(value => !property.Values.Any(v => v.Equals(value))))
+ {
+ property.Values.Add(value); //only add values that don't already exist
+ }
+ }
+
+ property.IsInitialized = true;
+ }
+
+ return property.Values.Cast();
+ }
+ }
+}
\ No newline at end of file
diff --git a/GBase/DataHandling/Cache/XmlDataHandlerCacheEntry.cs b/GBase/DataHandling/Cache/XmlDataHandlerCacheEntry.cs
new file mode 100644
index 0000000..850fb95
--- /dev/null
+++ b/GBase/DataHandling/Cache/XmlDataHandlerCacheEntry.cs
@@ -0,0 +1,41 @@
+// Author: Gockner, Simon
+// Created: 2020-02-12
+// Copyright(c) 2020 SimonG. All Rights Reserved.
+
+using System;
+using System.Collections.Generic;
+using GBase.Interfaces.DataHandling.Cache;
+using GBase.Interfaces.DataHandling.Xml.Cache;
+using GBase.Interfaces.DataHandling.Xml.Cache.Factories;
+
+namespace GBase.DataHandling.Cache
+{
+ ///
+ /// Entry for the
+ ///
+ public class XmlDataHandlerCacheEntry : IXmlDataHandlerCacheEntry
+ {
+ ///
+ /// Entry for the
+ ///
+ /// The that implements the property
+ /// The name of the property
+ /// The value of the property
+ /// Factory for the
+ public XmlDataHandlerCacheEntry(Type type, string propertyName, object value, IXmlDataHandlerCachePropertyEntryFactory xmlDataHandlerCachePropertyEntryFactory)
+ {
+ Type = type;
+ Properties = new List() { xmlDataHandlerCachePropertyEntryFactory.Create(propertyName, value) };
+ }
+
+ ///
+ /// The of the
+ ///
+ public Type Type { get; }
+
+ ///
+ /// The properties of the
+ ///
+ public List Properties { get; }
+ }
+}
\ No newline at end of file
diff --git a/GBase/DataHandling/Cache/XmlDataHandlerCachePropertyEntry.cs b/GBase/DataHandling/Cache/XmlDataHandlerCachePropertyEntry.cs
new file mode 100644
index 0000000..c1a7828
--- /dev/null
+++ b/GBase/DataHandling/Cache/XmlDataHandlerCachePropertyEntry.cs
@@ -0,0 +1,41 @@
+// Author: Gockner, Simon
+// Created: 2020-02-12
+// Copyright(c) 2020 SimonG. All Rights Reserved.
+
+using System.Collections.Generic;
+using GBase.Interfaces.DataHandling.Xml.Cache;
+
+namespace GBase.DataHandling.Cache
+{
+ ///
+ /// A property entry for the
+ ///
+ public class XmlDataHandlerCachePropertyEntry : IXmlDataHandlerCachePropertyEntry
+ {
+ ///
+ /// A property entry for the
+ ///
+ /// The name of the property
+ /// The value of the property
+ public XmlDataHandlerCachePropertyEntry(string propertyName, object value)
+ {
+ PropertyName = propertyName;
+ Values = new List() { value };
+ }
+
+ ///
+ /// The name of the property
+ ///
+ public string PropertyName { get; }
+
+ ///
+ /// This property is initialized in the
+ ///
+ public bool IsInitialized { get; set; }
+
+ ///
+ /// The values of the property
+ ///
+ public List Values { get; }
+ }
+}
\ No newline at end of file
diff --git a/GBase/DataHandling/XmlDataHandler.cs b/GBase/DataHandling/XmlDataHandler.cs
new file mode 100644
index 0000000..f0926c6
--- /dev/null
+++ b/GBase/DataHandling/XmlDataHandler.cs
@@ -0,0 +1,160 @@
+// Author: Gockner, Simon
+// Created: 2020-02-12
+// Copyright(c) 2020 SimonG. All Rights Reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using GBase.Interfaces.DataHandling;
+using GBase.Interfaces.DataHandling.Xml;
+using GBase.Interfaces.DataHandling.Xml.Cache;
+using GBase.Interfaces.DataHandling.Xml.Cache.Factories;
+using GBase.Interfaces.DataHandling.Xml.Factories;
+
+namespace GBase.DataHandling
+{
+ //TODO: access cache asynchronously?
+
+ ///
+ /// A that handles its data in an xml file
+ ///
+ public class XmlDataHandler : IXmlDataHandler
+ {
+ ///
+ /// The element name of the value element
+ ///
+ public const string VALUE_ELEMENT_NAME = "Value";
+
+ ///
+ /// The attribute name of the value attribute
+ ///
+ public const string VALUE_TYPE_ATTRIBUTE_NAME = "type";
+
+ private readonly IXmlDataReader _xmlDataReader;
+ private readonly IXmlDataWriter _xmlDataWriter;
+
+ private readonly IXmlDataHandlerCache _cache;
+
+ private bool _isInitialized;
+ private bool _overwrite;
+
+ ///
+ /// A that handles its data in an xml file
+ ///
+ /// The path to the xml file
+ /// The root element name of the xml file
+ /// The factory
+ /// The factory
+ /// The factory
+ public XmlDataHandler(string path,
+ string rootElementName,
+ IXmlDataReaderFactory xmlDataReaderFactory,
+ IXmlDataWriterFactory xmlDataWriterFactory,
+ IXmlDataHandlerCacheFactory xmlDataHandlerCacheFactory)
+ {
+ _xmlDataWriter = xmlDataWriterFactory.Create(path, rootElementName);
+ _xmlDataReader = xmlDataReaderFactory.Create(path);
+
+ _cache = xmlDataHandlerCacheFactory.Create(_xmlDataReader);
+ }
+
+ ///
+ /// Initialize the
+ ///
+ /// If true an existing value is overwritten, if false an additional value is added
+ /// A to cancel the async operation
+ /// Returns true if successful, false if not
+ public async Task Init(bool overwrite, CancellationToken cancellationToken)
+ {
+ if (_isInitialized)
+ return false;
+
+ _overwrite = overwrite;
+
+ if (!await _xmlDataWriter.Init(cancellationToken))
+ return false;
+
+ if (!await _xmlDataReader.Init(cancellationToken))
+ return false;
+
+ _isInitialized = true;
+
+ return true;
+ }
+
+ ///
+ /// Set the value for the given property
+ ///
+ /// The that implements the property
+ /// The of the property
+ /// The name of the property
+ /// The value to set
+ /// A to await
+ public async Task SetValue(string propertyName, TProperty value)
+ {
+ if (value == null)
+ return;
+
+ await _cache.SetValue(propertyName, value, _overwrite);
+ await _xmlDataWriter.Write(propertyName, value.ToString(), _overwrite);
+ }
+
+ ///
+ /// Remove the value for the given property
+ ///
+ /// The of the property
+ /// The of the property
+ /// The name of the property
+ /// The value to set
+ /// A to await
+ public async Task RemoveValue(string propertyName, TProperty value)
+ {
+ if (value == null)
+ return;
+
+ await _cache.TryRemoveValue(propertyName, value);
+ await _xmlDataWriter.Remove(propertyName, value.ToString());
+ }
+
+ ///
+ /// Get the value for the given property, if multiple values are set the first is returned
+ ///
+ /// The that implements the property
+ /// The of the property
+ /// The name of the property
+ /// The value for the given property
+ public async Task GetValue(string propertyName)
+ {
+ IEnumerable enumerable = await GetValues(propertyName);
+ return enumerable == null ? default : enumerable.FirstOrDefault();
+ }
+
+ ///
+ /// Get all the values that are set for the given property
+ ///
+ /// The that implements the property
+ /// The of the property
+ /// The name of the property
+ /// An with all the values for the property
+ public async Task> GetValues(string propertyName)
+ {
+ IEnumerable cachedValues = await _cache.TryGetValues(propertyName);
+ if (cachedValues != null)
+ return cachedValues;
+
+ return await _xmlDataReader.Read(propertyName);
+ }
+
+ ///
+ /// Dispose used resources asynchronously
+ ///
+ /// A to await
+ public async ValueTask DisposeAsync()
+ {
+ await _xmlDataReader.DisposeAsync();
+ await _xmlDataWriter.DisposeAsync();
+ }
+ }
+}
\ No newline at end of file
diff --git a/GBase/DataHandling/XmlDataReader.cs b/GBase/DataHandling/XmlDataReader.cs
new file mode 100644
index 0000000..979fe01
--- /dev/null
+++ b/GBase/DataHandling/XmlDataReader.cs
@@ -0,0 +1,104 @@
+// Author: Gockner, Simon
+// Created: 2020-02-12
+// Copyright(c) 2020 SimonG. All Rights Reserved.
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Xml.Linq;
+using GBase.Interfaces.DataHandling;
+using GBase.Interfaces.DataHandling.Xml;
+
+namespace GBase.DataHandling
+{
+ ///
+ /// A that reads from a xml file
+ ///
+ public class XmlDataReader : IXmlDataReader
+ {
+ private readonly FileStream _file;
+ private XDocument _xmlDocument;
+ private XElement _rootElement;
+
+ private bool _isInitialized;
+ private CancellationToken _cancellationToken;
+
+ ///
+ /// A that reads from a xml file
+ ///
+ /// The path to the xml file
+ public XmlDataReader(string path)
+ {
+ _file = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
+ }
+
+ ///
+ /// Initialize the
+ ///
+ /// A to cancel the async operation
+ /// Returns true if successful, false if not
+ public async Task Init(CancellationToken cancellationToken)
+ {
+ if (_isInitialized)
+ return false;
+
+ _cancellationToken = cancellationToken;
+ _xmlDocument = await XDocument.LoadAsync(_file, LoadOptions.None, _cancellationToken);
+
+ _rootElement = _xmlDocument.Root;
+ if (_rootElement == null)
+ throw new Exception("No root element found.");
+
+ _isInitialized = true;
+
+ return true;
+ }
+
+ ///
+ /// Read the data of a property
+ ///
+ /// The
+ /// The of the property
+ /// The name of the property
+ /// The data of the given property, null if no data found
+ public async Task> Read(string propertyName)
+ //TODO: Read currently doesn't work for newly added items -> probably because file was loaded before new items were added; is probably not a problem -> cache
+ {
+ string typeName = typeof(T).FullName;
+ if (typeName == null)
+ throw new ArgumentNullException(nameof(typeName));
+
+ return await Task.Run(() =>
+ {
+ XElement typeElement = _rootElement.Element(typeName);
+ XElement propertyElement = typeElement?.Element(propertyName);
+ XAttribute propertyTypeAttribute = propertyElement?.Attribute(XmlDataHandler.VALUE_TYPE_ATTRIBUTE_NAME);
+ if (propertyTypeAttribute == null)
+ return null;
+
+ Type propertyType = Type.GetType(propertyTypeAttribute.Value);
+ if (propertyType != typeof(TProperty))
+ throw new InvalidOperationException("Invalid Type found for the read object.");
+
+ List valueElements = propertyElement.Elements(XmlDataHandler.VALUE_ELEMENT_NAME).ToList();
+ if (!valueElements.Any())
+ return null;
+
+ IEnumerable values = valueElements.Select(v => v.Value);
+ return values.Select(value => (TProperty)Convert.ChangeType(value, typeof(TProperty))).ToList();
+ }, _cancellationToken);
+ }
+
+ ///
+ /// Dispose used resources asynchronously
+ ///
+ /// A to await
+ public async ValueTask DisposeAsync()
+ {
+ await _file.DisposeAsync();
+ }
+ }
+}
\ No newline at end of file
diff --git a/GBase/DataHandling/XmlDataWriter.cs b/GBase/DataHandling/XmlDataWriter.cs
new file mode 100644
index 0000000..f25f13d
--- /dev/null
+++ b/GBase/DataHandling/XmlDataWriter.cs
@@ -0,0 +1,168 @@
+// Author: Gockner, Simon
+// Created: 2020-02-12
+// Copyright(c) 2020 SimonG. All Rights Reserved.
+
+using System;
+using System.IO;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Xml.Linq;
+using GBase.Interfaces.DataHandling;
+using GBase.Interfaces.DataHandling.Xml;
+
+namespace GBase.DataHandling
+{
+ ///
+ /// A that writes to a xml file
+ ///
+ public class XmlDataWriter : IXmlDataWriter
+ {
+ private readonly string _rootElementName;
+ private readonly FileStream _file;
+
+ private XDocument _xmlDocument;
+ private XElement _rootElement;
+
+ private bool _isInitialized;
+ private CancellationToken _cancellationToken;
+
+ ///
+ /// A that writes to an xml file
+ ///
+ /// The path to the xml file
+ /// The root element name of the xml file
+ public XmlDataWriter(string path, string rootElementName)
+ {
+ _rootElementName = rootElementName;
+ _file = File.Open(path, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read);
+ }
+
+ ///
+ /// Initialize the
+ ///
+ /// A to cancel the async operation
+ /// Returns true if successful, false if not
+ public async Task Init(CancellationToken cancellationToken)
+ {
+ if (_isInitialized)
+ return false;
+
+ _cancellationToken = cancellationToken;
+ //if the xml file is empty, write the root element
+ if (_file.Length <= 3) //<= 3 because of BOM
+ {
+ _xmlDocument = new XDocument();
+ _xmlDocument.Add(new XElement(_rootElementName));
+ _file.Seek(0, SeekOrigin.Begin); //reset stream to it's beginning to be able to save it
+ await _xmlDocument.SaveAsync(_file, SaveOptions.OmitDuplicateNamespaces, cancellationToken);
+ }
+ else
+ {
+ _xmlDocument = await XDocument.LoadAsync(_file, LoadOptions.None, _cancellationToken);
+ }
+
+ _rootElement = _xmlDocument.Root;//?.Element(_rootElementName);
+ if (_rootElement == null)
+ throw new Exception("No root element found.");
+
+ _isInitialized = true;
+ return true;
+ }
+
+ ///
+ /// Write the data of a property
+ ///
+ /// The that implements the property
+ /// The of the property
+ /// The name of the property
+ /// The value of the property
+ /// If true an existing value is overwritten, if false an additional value is added
+ /// A to await
+ public async Task Write(string propertyName, string value, bool overwrite)
+ {
+ string typeName = typeof(T).FullName;
+ if (typeName == null)
+ throw new ArgumentNullException(nameof(typeName));
+
+ _file.Seek(0, SeekOrigin.Begin); //reset stream to it's beginning to be able to save it
+
+ XElement typeElement = _rootElement.Element(typeName);
+ if (typeElement != null) //type element already exists
+ {
+ XElement propertyElement = typeElement.Element(propertyName);
+ if (propertyElement != null) //property element already exists
+ {
+ XElement valueElement = propertyElement.Element(XmlDataHandler.VALUE_ELEMENT_NAME);
+ if (valueElement != null && overwrite) //value element exists and overwrite is true
+ {
+ valueElement.Value = value; //overwrite existing value
+ }
+ else if (!overwrite && propertyElement.Elements(XmlDataHandler.VALUE_ELEMENT_NAME).Any(v => v.Value.Equals(value))) //no overwrite and same value exists already
+ {
+ XElement sameValueElement = propertyElement.Elements(XmlDataHandler.VALUE_ELEMENT_NAME).First(v => v.Value.Equals(value));
+ sameValueElement.Remove(); //remove the already existing value from its current position
+ propertyElement.AddFirst(sameValueElement); //add it as the first element again
+ }
+ else //no value element exists or overwrite is false
+ propertyElement.AddFirst(new XElement(XmlDataHandler.VALUE_ELEMENT_NAME) { Value = value }); //add a new value element
+ }
+ else //property element doesn't exist
+ {
+ propertyElement = new XElement(propertyName, new XElement(XmlDataHandler.VALUE_ELEMENT_NAME) { Value = value }); //create the new property element with the value element
+ propertyElement.SetAttributeValue(XmlDataHandler.VALUE_TYPE_ATTRIBUTE_NAME, typeof(TProperty).FullName); //add the property type attribute
+
+ typeElement.Add(propertyElement); //create new property element with the value element
+ }
+ }
+ else //type element doesn't exist
+ {
+ XElement propertyElement = new XElement(propertyName, new XElement(XmlDataHandler.VALUE_ELEMENT_NAME) { Value = value }); //create the new property element with the value element
+ propertyElement.SetAttributeValue(XmlDataHandler.VALUE_TYPE_ATTRIBUTE_NAME, typeof(TProperty).FullName); //add the property type attribute
+
+ _rootElement.Add(new XElement(typeName, propertyElement)); //create a new type element with the new property element
+ }
+
+ //TODO: check if whole file is overwritten (probably) -> performance issues for large files?
+ await _xmlDocument.SaveAsync(_file, SaveOptions.OmitDuplicateNamespaces, _cancellationToken); //save the document with the added elements
+ }
+
+ ///
+ /// Remove the value for the given property
+ ///
+ /// The of the property
+ /// The of the property
+ /// The name of the property
+ /// The value to set
+ /// A to await
+ public async Task Remove(string propertyName, string value)
+ {
+ string typeName = typeof(T).FullName;
+ if (typeName == null)
+ throw new ArgumentNullException(nameof(typeName));
+
+ _file.Seek(0, SeekOrigin.Begin); //reset stream to it's beginning to be able to save it
+
+ XElement typeElement = _rootElement.Element(typeName);
+ XElement propertyElement = typeElement?.Element(propertyName);
+ XElement valueElement = propertyElement?.Elements(XmlDataHandler.VALUE_ELEMENT_NAME).FirstOrDefault(e => e.Value.Equals(value));
+ if (valueElement == null)
+ return;
+
+ valueElement.Remove();
+
+ //TODO: check if whole file is overwritten (probably) -> performance issues for large files?
+ await _xmlDocument.SaveAsync(_file, SaveOptions.OmitDuplicateNamespaces, _cancellationToken); //save the document with the added elements
+ }
+
+ ///
+ /// Dispose used resources asynchronously
+ ///
+ /// A to await
+ public async ValueTask DisposeAsync()
+ {
+ await _xmlDocument.SaveAsync(_file, SaveOptions.None, _cancellationToken);
+ await _file.DisposeAsync();
+ }
+ }
+}
\ No newline at end of file
diff --git a/GBase/Interfaces/DataHandling/Cache/IDataHandlerCache.cs b/GBase/Interfaces/DataHandling/Cache/IDataHandlerCache.cs
new file mode 100644
index 0000000..e02a452
--- /dev/null
+++ b/GBase/Interfaces/DataHandling/Cache/IDataHandlerCache.cs
@@ -0,0 +1,46 @@
+// Author: Gockner, Simon
+// Created: 2020-02-12
+// Copyright(c) 2020 SimonG. All Rights Reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace GBase.Interfaces.DataHandling.Cache
+{
+ ///
+ /// An interface for the
+ ///
+ public interface IDataHandlerCache
+ {
+ ///
+ /// Set the value for the given property
+ ///
+ /// The that implements the property
+ /// The of the property
+ /// The name of the property
+ /// The value to set
+ /// If true an existing value is overwritten, if false an additional value is added
+ /// A to await
+ Task SetValue(string propertyName, TProperty value, bool overwrite);
+
+ ///
+ /// Remove the value for the given property
+ ///
+ /// The of the property
+ /// The of the property
+ /// The name of the property
+ /// The value to set
+ /// A to await
+ Task TryRemoveValue(string propertyName, TProperty value);
+
+ ///
+ /// Try to get values from the cache for the given property
+ ///
+ /// The that implements the property
+ /// The of the property
+ /// The name of the property
+ /// An with all the values for the property
+ Task> TryGetValues(string propertyName);
+ }
+}
\ No newline at end of file
diff --git a/GBase/Interfaces/DataHandling/Cache/IDataHandlerCacheEntry.cs b/GBase/Interfaces/DataHandling/Cache/IDataHandlerCacheEntry.cs
new file mode 100644
index 0000000..0fe036b
--- /dev/null
+++ b/GBase/Interfaces/DataHandling/Cache/IDataHandlerCacheEntry.cs
@@ -0,0 +1,25 @@
+// Author: Gockner, Simon
+// Created: 2020-02-12
+// Copyright(c) 2020 SimonG. All Rights Reserved.
+
+using System;
+using System.Collections.Generic;
+
+namespace GBase.Interfaces.DataHandling.Cache
+{
+ ///
+ /// Entry for the
+ ///
+ public interface IDataHandlerCacheEntry
+ {
+ ///
+ /// The of the
+ ///
+ Type Type { get; }
+
+ ///
+ /// The properties of the
+ ///
+ List Properties { get; }
+ }
+}
\ No newline at end of file
diff --git a/GBase/Interfaces/DataHandling/Cache/IDataHandlerCachePropertyEntry.cs b/GBase/Interfaces/DataHandling/Cache/IDataHandlerCachePropertyEntry.cs
new file mode 100644
index 0000000..40b888f
--- /dev/null
+++ b/GBase/Interfaces/DataHandling/Cache/IDataHandlerCachePropertyEntry.cs
@@ -0,0 +1,29 @@
+// Author: Gockner, Simon
+// Created: 2020-02-12
+// Copyright(c) 2020 SimonG. All Rights Reserved.
+
+using System.Collections.Generic;
+
+namespace GBase.Interfaces.DataHandling.Cache
+{
+ ///
+ /// A property entry for the
+ ///
+ public interface IDataHandlerCachePropertyEntry
+ {
+ ///
+ /// The name of the property
+ ///
+ string PropertyName { get; }
+
+ ///
+ /// This property is initialized in the
+ ///
+ bool IsInitialized { get; set; }
+
+ ///
+ /// The values of the property
+ ///
+ List Values { get; }
+ }
+}
\ No newline at end of file
diff --git a/GBase/Interfaces/DataHandling/IDataHandler.cs b/GBase/Interfaces/DataHandling/IDataHandler.cs
new file mode 100644
index 0000000..cc600be
--- /dev/null
+++ b/GBase/Interfaces/DataHandling/IDataHandler.cs
@@ -0,0 +1,63 @@
+// Author: Gockner, Simon
+// Created: 2020-02-12
+// Copyright(c) 2020 SimonG. All Rights Reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace GBase.Interfaces.DataHandling
+{
+ ///
+ /// Interface for data handlers to implement
+ ///
+ public interface IDataHandler : IAsyncDisposable
+ {
+ ///
+ /// Initialize the
+ ///
+ /// If true an existing value is overwritten, if false an additional value is added
+ /// A to cancel the async operation
+ /// Returns true if successful, false if not
+ Task Init(bool overwrite, CancellationToken cancellationToken);
+
+ ///
+ /// Set the value for the given property
+ ///
+ /// The of the property
+ /// The of the property
+ /// The name of the property
+ /// The value to set
+ /// A to await
+ Task SetValue(string propertyName, TProperty value);
+
+ ///
+ /// Remove the value for the given property
+ ///
+ /// The of the property
+ /// The of the property
+ /// The name of the property
+ /// The value to set
+ /// A to await
+ Task RemoveValue(string propertyName, TProperty value);
+
+ ///
+ /// Get the value for the given property, if multiple values are set the first is returned
+ ///
+ /// The of the property
+ /// The of the property
+ /// The name of the property
+ /// The value for the given property
+ Task GetValue(string propertyName);
+
+ ///
+ /// Get all the values that are set for the given property
+ ///
+ /// The of the property
+ /// The of the property
+ /// The name of the property
+ /// An with all the values for the property
+ Task> GetValues(string propertyName);
+ }
+}
\ No newline at end of file
diff --git a/GBase/Interfaces/DataHandling/IDataReader.cs b/GBase/Interfaces/DataHandling/IDataReader.cs
new file mode 100644
index 0000000..e6d34da
--- /dev/null
+++ b/GBase/Interfaces/DataHandling/IDataReader.cs
@@ -0,0 +1,33 @@
+// Author: Gockner, Simon
+// Created: 2020-02-12
+// Copyright(c) 2020 SimonG. All Rights Reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace GBase.Interfaces.DataHandling
+{
+ ///
+ /// Interface for data readers to implement
+ ///
+ public interface IDataReader : IAsyncDisposable
+ {
+ ///
+ /// Initialize the
+ ///
+ /// A to cancel the async operation
+ /// Returns true if successful, false if not
+ Task Init(CancellationToken cancellationToken);
+
+ ///
+ /// Read the data of a property
+ ///
+ /// The
+ /// The of the property
+ /// The name of the property
+ /// The data of the given property, null if no data found
+ Task> Read(string propertyName);
+ }
+}
\ No newline at end of file
diff --git a/GBase/Interfaces/DataHandling/IDataWriter.cs b/GBase/Interfaces/DataHandling/IDataWriter.cs
new file mode 100644
index 0000000..c049b66
--- /dev/null
+++ b/GBase/Interfaces/DataHandling/IDataWriter.cs
@@ -0,0 +1,44 @@
+// Author: Gockner, Simon
+// Created: 2020-02-12
+// Copyright(c) 2020 SimonG. All Rights Reserved.
+
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace GBase.Interfaces.DataHandling
+{
+ ///
+ /// Interface for data writers to implement
+ ///
+ public interface IDataWriter : IAsyncDisposable
+ {
+ ///
+ /// Initialize the
+ ///
+ /// A to cancel the async operation
+ /// Returns true if successful, false if not
+ Task Init(CancellationToken cancellationToken);
+
+ ///
+ /// Write the data of a property
+ ///
+ /// The
+ /// The of the property
+ /// The name of the property
+ /// The value of the property
+ /// If true an existing value is overwritten, if false an additional value is added
+ /// A to await
+ Task Write(string propertyName, string value, bool overwrite);
+
+ ///
+ /// Remove the value for the given property
+ ///
+ /// The of the property
+ /// The of the property
+ /// The name of the property
+ /// The value to set
+ /// A to await
+ Task Remove(string propertyName, string value);
+ }
+}
\ No newline at end of file
diff --git a/GBase/Interfaces/DataHandling/Xml/Cache/Factories/IXmlDataHandlerCacheEntryFactory.cs b/GBase/Interfaces/DataHandling/Xml/Cache/Factories/IXmlDataHandlerCacheEntryFactory.cs
new file mode 100644
index 0000000..fce263e
--- /dev/null
+++ b/GBase/Interfaces/DataHandling/Xml/Cache/Factories/IXmlDataHandlerCacheEntryFactory.cs
@@ -0,0 +1,13 @@
+// Author: Gockner, Simon
+// Created: 2020-02-12
+// Copyright(c) 2020 SimonG. All Rights Reserved.
+
+using System;
+
+namespace GBase.Interfaces.DataHandling.Xml.Cache.Factories
+{
+ public interface IXmlDataHandlerCacheEntryFactory
+ {
+ IXmlDataHandlerCacheEntry Create(Type type, string propertyName, object value);
+ }
+}
\ No newline at end of file
diff --git a/GBase/Interfaces/DataHandling/Xml/Cache/Factories/IXmlDataHandlerCacheFactory.cs b/GBase/Interfaces/DataHandling/Xml/Cache/Factories/IXmlDataHandlerCacheFactory.cs
new file mode 100644
index 0000000..ffb517f
--- /dev/null
+++ b/GBase/Interfaces/DataHandling/Xml/Cache/Factories/IXmlDataHandlerCacheFactory.cs
@@ -0,0 +1,11 @@
+// Author: Gockner, Simon
+// Created: 2020-02-12
+// Copyright(c) 2020 SimonG. All Rights Reserved.
+
+namespace GBase.Interfaces.DataHandling.Xml.Cache.Factories
+{
+ public interface IXmlDataHandlerCacheFactory
+ {
+ IXmlDataHandlerCache Create(IXmlDataReader xmlDataReader);
+ }
+}
\ No newline at end of file
diff --git a/GBase/Interfaces/DataHandling/Xml/Cache/Factories/IXmlDataHandlerCachePropertyEntryFactory.cs b/GBase/Interfaces/DataHandling/Xml/Cache/Factories/IXmlDataHandlerCachePropertyEntryFactory.cs
new file mode 100644
index 0000000..23ef25c
--- /dev/null
+++ b/GBase/Interfaces/DataHandling/Xml/Cache/Factories/IXmlDataHandlerCachePropertyEntryFactory.cs
@@ -0,0 +1,11 @@
+// Author: Gockner, Simon
+// Created: 2020-02-12
+// Copyright(c) 2020 SimonG. All Rights Reserved.
+
+namespace GBase.Interfaces.DataHandling.Xml.Cache.Factories
+{
+ public interface IXmlDataHandlerCachePropertyEntryFactory
+ {
+ IXmlDataHandlerCachePropertyEntry Create(string propertyName, object value);
+ }
+}
\ No newline at end of file
diff --git a/GBase/Interfaces/DataHandling/Xml/Cache/IXmlDataHandlerCache.cs b/GBase/Interfaces/DataHandling/Xml/Cache/IXmlDataHandlerCache.cs
new file mode 100644
index 0000000..cbd5c23
--- /dev/null
+++ b/GBase/Interfaces/DataHandling/Xml/Cache/IXmlDataHandlerCache.cs
@@ -0,0 +1,16 @@
+// Author: Gockner, Simon
+// Created: 2020-02-12
+// Copyright(c) 2020 SimonG. All Rights Reserved.
+
+using GBase.Interfaces.DataHandling.Cache;
+
+namespace GBase.Interfaces.DataHandling.Xml.Cache
+{
+ ///
+ /// An interface for the
+ ///
+ public interface IXmlDataHandlerCache : IDataHandlerCache
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/GBase/Interfaces/DataHandling/Xml/Cache/IXmlDataHandlerCacheEntry.cs b/GBase/Interfaces/DataHandling/Xml/Cache/IXmlDataHandlerCacheEntry.cs
new file mode 100644
index 0000000..cc2506c
--- /dev/null
+++ b/GBase/Interfaces/DataHandling/Xml/Cache/IXmlDataHandlerCacheEntry.cs
@@ -0,0 +1,16 @@
+// Author: Gockner, Simon
+// Created: 2020-02-12
+// Copyright(c) 2020 SimonG. All Rights Reserved.
+
+using GBase.Interfaces.DataHandling.Cache;
+
+namespace GBase.Interfaces.DataHandling.Xml.Cache
+{
+ ///
+ /// Entry for the
+ ///
+ public interface IXmlDataHandlerCacheEntry : IDataHandlerCacheEntry
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/GBase/Interfaces/DataHandling/Xml/Cache/IXmlDataHandlerCachePropertyEntry.cs b/GBase/Interfaces/DataHandling/Xml/Cache/IXmlDataHandlerCachePropertyEntry.cs
new file mode 100644
index 0000000..ba7ec22
--- /dev/null
+++ b/GBase/Interfaces/DataHandling/Xml/Cache/IXmlDataHandlerCachePropertyEntry.cs
@@ -0,0 +1,16 @@
+// Author: Gockner, Simon
+// Created: 2020-02-12
+// Copyright(c) 2020 SimonG. All Rights Reserved.
+
+using GBase.Interfaces.DataHandling.Cache;
+
+namespace GBase.Interfaces.DataHandling.Xml.Cache
+{
+ ///
+ /// A property entry for the
+ ///
+ public interface IXmlDataHandlerCachePropertyEntry : IDataHandlerCachePropertyEntry
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/GBase/Interfaces/DataHandling/Xml/Factories/IXmlDataHandlerFactory.cs b/GBase/Interfaces/DataHandling/Xml/Factories/IXmlDataHandlerFactory.cs
new file mode 100644
index 0000000..52b5f53
--- /dev/null
+++ b/GBase/Interfaces/DataHandling/Xml/Factories/IXmlDataHandlerFactory.cs
@@ -0,0 +1,11 @@
+// Author: Gockner, Simon
+// Created: 2020-02-12
+// Copyright(c) 2020 SimonG. All Rights Reserved.
+
+namespace GBase.Interfaces.DataHandling.Xml.Factories
+{
+ public interface IXmlDataHandlerFactory
+ {
+ IXmlDataHandler Create();
+ }
+}
\ No newline at end of file
diff --git a/GBase/Interfaces/DataHandling/Xml/Factories/IXmlDataReaderFactory.cs b/GBase/Interfaces/DataHandling/Xml/Factories/IXmlDataReaderFactory.cs
new file mode 100644
index 0000000..e573acd
--- /dev/null
+++ b/GBase/Interfaces/DataHandling/Xml/Factories/IXmlDataReaderFactory.cs
@@ -0,0 +1,11 @@
+// Author: Gockner, Simon
+// Created: 2020-02-12
+// Copyright(c) 2020 SimonG. All Rights Reserved.
+
+namespace GBase.Interfaces.DataHandling.Xml.Factories
+{
+ public interface IXmlDataReaderFactory
+ {
+ IXmlDataReader Create(string path);
+ }
+}
\ No newline at end of file
diff --git a/GBase/Interfaces/DataHandling/Xml/Factories/IXmlDataWriterFactory.cs b/GBase/Interfaces/DataHandling/Xml/Factories/IXmlDataWriterFactory.cs
new file mode 100644
index 0000000..9c2db97
--- /dev/null
+++ b/GBase/Interfaces/DataHandling/Xml/Factories/IXmlDataWriterFactory.cs
@@ -0,0 +1,11 @@
+// Author: Gockner, Simon
+// Created: 2020-02-12
+// Copyright(c) 2020 SimonG. All Rights Reserved.
+
+namespace GBase.Interfaces.DataHandling.Xml.Factories
+{
+ public interface IXmlDataWriterFactory
+ {
+ IXmlDataWriter Create(string path, string rootElementName);
+ }
+}
\ No newline at end of file
diff --git a/GBase/Interfaces/DataHandling/Xml/IXmlDataHandler.cs b/GBase/Interfaces/DataHandling/Xml/IXmlDataHandler.cs
new file mode 100644
index 0000000..acc4845
--- /dev/null
+++ b/GBase/Interfaces/DataHandling/Xml/IXmlDataHandler.cs
@@ -0,0 +1,14 @@
+// Author: Gockner, Simon
+// Created: 2020-02-12
+// Copyright(c) 2020 SimonG. All Rights Reserved.
+
+namespace GBase.Interfaces.DataHandling.Xml
+{
+ ///
+ /// A that handles its data in an xml file
+ ///
+ public interface IXmlDataHandler : IDataHandler
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/GBase/Interfaces/DataHandling/Xml/IXmlDataReader.cs b/GBase/Interfaces/DataHandling/Xml/IXmlDataReader.cs
new file mode 100644
index 0000000..09122ef
--- /dev/null
+++ b/GBase/Interfaces/DataHandling/Xml/IXmlDataReader.cs
@@ -0,0 +1,14 @@
+// Author: Gockner, Simon
+// Created: 2020-02-12
+// Copyright(c) 2020 SimonG. All Rights Reserved.
+
+namespace GBase.Interfaces.DataHandling.Xml
+{
+ ///
+ /// A that writes to an xml file
+ ///
+ public interface IXmlDataReader : IDataReader
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/GBase/Interfaces/DataHandling/Xml/IXmlDataWriter.cs b/GBase/Interfaces/DataHandling/Xml/IXmlDataWriter.cs
new file mode 100644
index 0000000..33a91b6
--- /dev/null
+++ b/GBase/Interfaces/DataHandling/Xml/IXmlDataWriter.cs
@@ -0,0 +1,14 @@
+// Author: Gockner, Simon
+// Created: 2020-02-12
+// Copyright(c) 2020 SimonG. All Rights Reserved.
+
+namespace GBase.Interfaces.DataHandling.Xml
+{
+ ///
+ /// An that writes to a xml file
+ ///
+ public interface IXmlDataWriter : IDataWriter
+ {
+
+ }
+}
\ No newline at end of file