using Model; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; using System.Xml; using System.Xml.Linq; namespace DataPersistence { /// /// Define a serializer to manage XML files. /// public class DataContractXML : IDataManager { #region Attributes private string _xmlFolderPath; private XmlWriterSettings _xmlWriterSettings; private DataContractSerializerSettings _dataContractSerializerSettings; #endregion #region Constructors /// /// Constructor of a DataContractXML serializer. /// /// Give the default path where to load and save the data (by default is the current execution dir). /// Give another set of XML setting to write file. /// Give another set of DataContract serializer setting to write file public DataContractXML(string xmlFolderPath = "", XmlWriterSettings? xmlWriterSettings = null, DataContractSerializerSettings? dataContractSerializerSettings = null) { _xmlFolderPath = xmlFolderPath; if (xmlWriterSettings is null) _xmlWriterSettings = new XmlWriterSettings() { Indent = true }; else _xmlWriterSettings = xmlWriterSettings; if (dataContractSerializerSettings is null) _dataContractSerializerSettings = new DataContractSerializerSettings() { KnownTypes = new Type[] { typeof(Recipe), typeof(Review), typeof(User), typeof(Ingredient), typeof(Quantity), typeof(PasswordSHA256) }, PreserveObjectReferences = true }; else _dataContractSerializerSettings = dataContractSerializerSettings; } #endregion #region IDataManager implementation public void Export(T obj, string pathToExport) where T : class { bool restore = _dataContractSerializerSettings.PreserveObjectReferences; _dataContractSerializerSettings.PreserveObjectReferences = false; var serializer = new DataContractSerializer(typeof(T), _dataContractSerializerSettings); using (TextWriter textWriter = File.CreateText(Path.Combine(_xmlFolderPath, pathToExport))) { using (XmlWriter xmlWriter = XmlWriter.Create(textWriter, _xmlWriterSettings)) { serializer.WriteObject(xmlWriter, obj); } } _dataContractSerializerSettings.PreserveObjectReferences = restore; } public KeyValuePair Import(string pathToImport) where T : class { T? obj; var serializer = new DataContractSerializer(typeof(T), _dataContractSerializerSettings); using (Stream s = File.OpenRead(Path.Combine(_xmlFolderPath, pathToImport))) { obj = serializer.ReadObject(s) as T; } if (obj is null) throw new ArgumentNullException("obj"); string typeName = typeof(T).Name; return new KeyValuePair(typeName, obj); } public Dictionary> Load() { Dictionary>? elements; var serializer = new DataContractSerializer(typeof(Dictionary>), _dataContractSerializerSettings); using (Stream s = File.OpenRead(Path.Combine(_xmlFolderPath, "data.xml"))) { elements = serializer.ReadObject(s) as Dictionary>; } if (elements is null) throw new ArgumentNullException("elements"); return elements; } public void Save(Dictionary> elements) { var serializer = new DataContractSerializer(typeof(Dictionary>), _dataContractSerializerSettings); using (TextWriter textWriter = File.CreateText(Path.Combine(_xmlFolderPath, "data.xml"))) { using (XmlWriter xmlWriter = XmlWriter.Create(textWriter, _xmlWriterSettings)) { serializer.WriteObject(xmlWriter, elements); } } } #endregion } }