Serialize converters were added

This commit is contained in:
Evgeny Redikultsev
2024-09-08 17:47:46 +05:00
parent 408e9f6999
commit 6e0b7b8070
60 changed files with 1713 additions and 443 deletions

View File

@@ -0,0 +1,27 @@
using Newtonsoft.Json;
using StructureHelperCommon.Models.Projects;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DataAccess.DTOs
{
[JsonObject(IsReference = true)]
public class FileVersionDTO : IFileVersion
{
[JsonProperty("Id")]
public Guid Id { get; set; }
[JsonProperty("VersionNumber")]
public int VersionNumber { get; set; }
[JsonProperty("SubVersionNumber")]
public int SubVersionNumber { get; set; }
public FileVersionDTO(Guid id)
{
Id = id;
}
}
}

View File

@@ -0,0 +1,41 @@
using StructureHelperCommon.Infrastructures.Interfaces;
using StructureHelperCommon.Models;
using StructureHelperCommon.Models.Projects;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DataAccess.DTOs
{
public class FileVersionDTOConvertStrategy : IConvertStrategy<FileVersion, FileVersionDTO>
{
private IUpdateStrategy<IFileVersion> updateStrategy;
public IShiftTraceLogger TraceLogger { get; set; }
public FileVersionDTOConvertStrategy(IUpdateStrategy<IFileVersion> updateStrategy)
{
this.updateStrategy = updateStrategy;
}
public FileVersionDTOConvertStrategy() : this(new FileVersionUpdateStrategy())
{
}
public FileVersionDTO ConvertTo(FileVersion source)
{
FileVersionDTO fileVersion = new(source.Id);
updateStrategy.Update(fileVersion, source);
return fileVersion;
}
public FileVersion ConvertFrom(FileVersionDTO source)
{
FileVersion fileVersion = new(source.Id);
updateStrategy.Update(fileVersion, source);
return fileVersion;
}
}
}

View File

@@ -0,0 +1,35 @@
using Newtonsoft.Json;
using StructureHelperCommon.Models.Analyses;
using StructureHelperCommon.Models.Projects;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DataAccess.DTOs
{
public class ProjectDTO : IProject
{
[JsonProperty("Id")]
public Guid Id { get; set; }
[JsonIgnore]
public string FullFileName { get; set; }
[JsonIgnore]
public bool IsNewFile { get; set; }
[JsonIgnore]
public bool IsActual { get; set; }
[JsonProperty("VisualAnalyses")]
public List<IVisualAnalysis> VisualAnalyses { get; private set; }
[JsonIgnore]
public string FileName { get; set; }
public ProjectDTO(Guid id)
{
Id = id;
}
}
}

View File

@@ -15,4 +15,8 @@
<ProjectReference Include="..\StructureHelperLogics\StructureHelperLogics.csproj" /> <ProjectReference Include="..\StructureHelperLogics\StructureHelperLogics.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="NewFolder\" />
</ItemGroup>
</Project> </Project>

View File

@@ -1,124 +1,113 @@
using System; using Newtonsoft.Json;
using System.Collections.Generic; using StructureHelperCommon.Models;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DataAccess namespace DataAccess
{ {
using Newtonsoft.Json;
using StructureHelperCommon.Models;
using System;
using System.Collections.Generic;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.ListView;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.TextBox;
class Program // class Program
{ // {
static void Main(string[] args) // static void Main(string[] args)
{ // {
var logger = new TraceLogger(); // var logger = new TraceLogger();
// Create objects with complex relationships // // Create objects with complex relationships
var parent1 = new Parent { Name = "Parent_1" }; // var parent1 = new Parent { Name = "Parent_1" };
var parent2 = new Parent { Name = "Parent_2" }; // var parent2 = new Parent { Name = "Parent_2" };
var detail1 = new Detail { Description = "Detail_1", InternalNote = "Secret Note 1" }; // var detail1 = new Detail { Description = "Detail_1", InternalNote = "Secret Note 1" };
var detail2 = new Detail { Description = "Detail_2", InternalNote = "Secret Note 2" }; // var detail2 = new Detail { Description = "Detail_2", InternalNote = "Secret Note 2" };
var detail3 = new Detail { Description = "Detail_3", InternalNote = "Secret Note 3" }; // var detail3 = new Detail { Description = "Detail_3", InternalNote = "Secret Note 3" };
var subDetail1 = new SubDetail { Info = "SubDetail_1" }; // var subDetail1 = new SubDetail { Info = "SubDetail_1" };
// Set up relationships // // Set up relationships
parent1.Details.Add(detail1); // parent1.Details.Add(detail1);
parent1.Details.Add(detail2); // parent1.Details.Add(detail2);
parent2.Details.Add(detail2); // Shared detail // parent2.Details.Add(detail2); // Shared detail
parent2.Details.Add(detail3); // parent2.Details.Add(detail3);
detail3.SubDetails.Add(subDetail1); // detail3.SubDetails.Add(subDetail1);
// Serialize with custom converters and trace logging // // Serialize with custom converters and trace logging
string json = Serialize(new List<Parent> { parent1, parent2 }, logger); // string json = Serialize(new List<Parent> { parent1, parent2 }, logger);
Console.WriteLine("Serialized JSON:"); // Console.WriteLine("Serialized JSON:");
Console.WriteLine(json); // Console.WriteLine(json);
// Deserialize with custom converters and trace logging // // Deserialize with custom converters and trace logging
var deserializedParents = Deserialize<List<Parent>>(json, logger); // var deserializedParents = Deserialize<List<Parent>>(json, logger);
Console.WriteLine("\nDeserialized Objects:"); // Console.WriteLine("\nDeserialized Objects:");
foreach (var parent in deserializedParents) // foreach (var parent in deserializedParents)
{ // {
Console.WriteLine($"Parent: {parent.Name}, Id: {parent.Id}"); // Console.WriteLine($"Parent: {parent.Name}, Id: {parent.Id}");
foreach (var detail in parent.Details) // foreach (var detail in parent.Details)
{ // {
Console.WriteLine($" Detail: {detail.Description}, Id: {detail.Id}"); // Console.WriteLine($" Detail: {detail.Description}, Id: {detail.Id}");
} // }
} // }
} // }
static string Serialize(object obj, TraceLogger logger) // static string Serialize(object obj, TraceLogger logger)
{ // {
var settings = new JsonSerializerSettings // var settings = new JsonSerializerSettings
{ // {
Converters = new List<JsonConverter> // Converters = new List<JsonConverter>
{ // {
new ParentConverter(logger), // Add the specific converter // new ParentConverter(logger), // Add the specific converter
// Add other converters if needed // // Add other converters if needed
}, // },
Formatting = Formatting.Indented // Formatting = Formatting.Indented
}; // };
return JsonConvert.SerializeObject(obj, settings); // return JsonConvert.SerializeObject(obj, settings);
} // }
static T Deserialize<T>(string json, TraceLogger logger) // static T Deserialize<T>(string json, TraceLogger logger)
{ // {
var settings = new JsonSerializerSettings // var settings = new JsonSerializerSettings
{ // {
Converters = new List<JsonConverter> // Converters = new List<JsonConverter>
{ // {
new ParentConverter(logger), // Add the specific converter // new ParentConverter(logger), // Add the specific converter
// Add other converters if needed // // Add other converters if needed
} // }
}; // };
return JsonConvert.DeserializeObject<T>(json, settings); // return JsonConvert.DeserializeObject<T>(json, settings);
} // }
} // }
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
public class Parent
{
public Guid Id { get; set; } = Guid.NewGuid();
[JsonProperty("parent_name")] //public class Parent
public string Name { get; set; } // {
// public Guid Id { get; set; } = Guid.NewGuid();
public List<Detail> Details { get; set; } = new List<Detail>(); // [JsonProperty("parent_name")]
} // public string Name { get; set; }
public class Detail // public List<Detail> Details { get; set; } = new List<Detail>();
{ // }
public Guid Id { get; set; } = Guid.NewGuid();
[JsonPropertyName("detail_description")] // Compatible with System.Text.Json // public class Detail
public string Description { get; set; } // {
// public Guid Id { get; set; } = Guid.NewGuid();
[JsonIgnore] // This property will be ignored during serialization // [JsonPropertyName("detail_description")] // Compatible with System.Text.Json
public string InternalNote { get; set; } // public string Description { get; set; }
public List<SubDetail> SubDetails { get; set; } = new List<SubDetail>(); // [JsonIgnore] // This property will be ignored during serialization
} // public string InternalNote { get; set; }
public class SubDetail // public List<SubDetail> SubDetails { get; set; } = new List<SubDetail>();
{ // }
public Guid Id { get; set; } = Guid.NewGuid();
public string Info { get; set; } // public class SubDetail
} // {
// public Guid Id { get; set; } = Guid.NewGuid();
// public string Info { get; set; }
// }
} }

View File

@@ -1,49 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace DataAccess.FileDialogs
{
public class FileDialogOpener
{
public void OpenFileAndRead()
{
// Create an instance of OpenFileDialog
using (OpenFileDialog openFileDialog = new OpenFileDialog())
{
// Set filter options and filter index
openFileDialog.Filter = "Text Files (*.txt)|*.txt|All Files (*.*)|*.*";
openFileDialog.FilterIndex = 1;
openFileDialog.Multiselect = false; // Set to true if you want to allow multiple file selection
openFileDialog.Title = "Select a File";
// Show the dialog and get result
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
// Get the path of the selected file
string selectedFilePath = openFileDialog.FileName;
// Read the content of the file
try
{
string fileContent = File.ReadAllText(selectedFilePath);
Console.WriteLine($"File Content of '{selectedFilePath}':");
Console.WriteLine(fileContent);
}
catch (IOException ex)
{
Console.WriteLine($"An error occurred while reading the file: {ex.Message}");
}
}
else
{
Console.WriteLine("File selection was cancelled.");
}
}
}
}
}

View File

@@ -10,10 +10,6 @@ namespace DataAccess.FileDialogs
{ {
internal class FileStorage internal class FileStorage
{ {
using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
public class FileStorageManager public class FileStorageManager
{ {
@@ -109,30 +105,30 @@ class Program
[STAThread] // Required for OpenFileDialog [STAThread] // Required for OpenFileDialog
static void Main() static void Main()
{ {
var fileStorageManager = new FileStorageManager(); //var fileStorageManager = new FileStorageManager();
// Open files and add them to the storage //// Open files and add them to the storage
fileStorageManager.OpenFile(); //fileStorageManager.OpenFile();
// List all opened files //// List all opened files
Console.WriteLine("\nOpened Files:"); //Console.WriteLine("\nOpened Files:");
fileStorageManager.ListOpenedFiles(); //fileStorageManager.ListOpenedFiles();
// Example: Read content of the first opened file (if any) //// Example: Read content of the first opened file (if any)
var openedFiles = new List<Guid>(fileStorageManager._openedFiles.Keys); //var openedFiles = new List<Guid>(fileStorageManager._openedFiles.Keys);
if (openedFiles.Count > 0) //if (openedFiles.Count > 0)
{ //{
var firstFileId = openedFiles[0]; // var firstFileId = openedFiles[0];
Console.WriteLine($"\nReading content of the first opened file (ID: {firstFileId}):"); // Console.WriteLine($"\nReading content of the first opened file (ID: {firstFileId}):");
string content = fileStorageManager.ReadFileContent(firstFileId); // string content = fileStorageManager.ReadFileContent(firstFileId);
Console.WriteLine(content); // Console.WriteLine(content);
} //}
// Close all files //// Close all files
foreach (var fileId in openedFiles) //foreach (var fileId in openedFiles)
{ //{
fileStorageManager.CloseFile(fileId); // fileStorageManager.CloseFile(fileId);
} //}
} }
} }

View File

@@ -0,0 +1,90 @@
using DataAccess.DTOs;
using DataAccess.JsonConverters;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NLog;
using StructureHelperCommon.Infrastructures.Settings;
using StructureHelperCommon.Models;
using StructureHelperCommon.Models.Projects;
using StructureHelperCommon.Services.FileServices;
namespace DataAccess.Infrastructures
{
public class FileOpenLogic : IFileOpenLogic
{
private string fileName;
public IShiftTraceLogger? TraceLogger { get; set; }
private bool GetFilePath()
{
var inputData = new OpenFileInputData()
{
FilterString = "StructureHelper project file (*.shpj)|*.shpj|All Files (*.*)|*.*",
TraceLogger = TraceLogger
};
var fileDialog = new FileOpener(inputData);
var fileDialogResult = fileDialog.OpenFile();
if (fileDialogResult.IsValid != true)
{
return false;
}
fileName = fileDialogResult.FilePath;
return true;
}
public OpenProjectResult OpenFile()
{
var result = new OpenProjectResult()
{
IsValid = true
};
if (GetFilePath() == false)
{
result.IsValid = false;
return result;
}
if (! File.Exists(fileName))
{
result.IsValid = false;
TraceLogger?.AddMessage($"File {fileName} does not exists", TraceLogStatuses.Error);
return result;
}
var settings = new JsonSerializerSettings
{
Converters = new List<JsonConverter>
{
new FileVersionDTOJsonConverter(TraceLogger), // Add the specific converter
// Add other converters if needed
},
Formatting = Formatting.Indented,
PreserveReferencesHandling = PreserveReferencesHandling.All,
MissingMemberHandling = MissingMemberHandling.Ignore,
TypeNameHandling = TypeNameHandling.All,
NullValueHandling = NullValueHandling.Include
};
using (StreamReader file = File.OpenText(fileName))
{
JsonSerializer serializer = new JsonSerializer();
var fileVersion = (FileVersionDTO)serializer.Deserialize(file, typeof(FileVersionDTO));
var checkLogic = new CheckFileVersionLogic()
{
FileVersion = fileVersion,
TraceLogger = TraceLogger
};
var checkResult = checkLogic.Check();
if (checkResult == false)
{
result.IsValid = false;
result.Description += checkLogic.CheckResult;
}
else
{
var currentVersion = ProgramSetting.GetCurrentFileVersion();
TraceLogger.AddMessage($"File version is {fileVersion.VersionNumber}.{fileVersion.SubVersionNumber}, current version is {currentVersion.VersionNumber}.{currentVersion.SubVersionNumber}");
}
}
return result;
}
}
}

View File

@@ -0,0 +1,114 @@
using DataAccess.DTOs;
using DataAccess.JsonConverters;
using Newtonsoft.Json;
using StructureHelperCommon.Infrastructures.Interfaces;
using StructureHelperCommon.Infrastructures.Settings;
using StructureHelperCommon.Models;
using StructureHelperCommon.Models.Projects;
using StructureHelperCommon.Services.FileServices;
namespace DataAccess.Infrastructures
{
public class FileSaveLogic : IFileSaveLogic
{
private IFileVersion version;
private Dictionary<(Guid id, Type type), ISaveable> refDictinary;
public IShiftTraceLogger? TraceLogger { get; set; }
public void SaveFile(IProject project)
{
if (project.IsNewFile == true)
{
var result = SelectFileName(project);
if (result.IsValid == false)
{
TraceLogger?.AddMessage(result.Description);
return;
}
project.FullFileName = result.FileName;
project.IsNewFile = false;
}
SaveToFile(project);
}
private SaveFileResult SelectFileName(IProject project)
{
FileDialogSaver saver = new();
saver.InputData = new SaveDialogInputData()
{
FilterString = "StructureHelper project file (*.shpj)|*.shpj|All Files (*.*)|*.*",
InitialDirectory = project.FullFileName,
};
saver.TraceLogger = TraceLogger;
var saveResult = saver.SaveFile();
return saveResult;
}
private void SaveToFile(IProject project)
{
version = ProgramSetting.GetCurrentFileVersion();
refDictinary = new Dictionary<(Guid id, Type type), ISaveable>();
FileVersionDTO versionDTO = GetVersionDTO();
var versionString = Serialize(versionDTO, TraceLogger);
try
{
File.WriteAllText(project.FullFileName, versionString);
TraceLogger?.AddMessage($"File {project.FullFileName} was saved successfully", TraceLogStatuses.Service);
}
catch (Exception ex)
{
TraceLogger?.AddMessage(ex.Message, TraceLogStatuses.Error);
}
}
private FileVersionDTO GetVersionDTO()
{
FileVersionDTOConvertStrategy fileVersionDTOConvertStrategy = new()
{
TraceLogger = TraceLogger
};
DictionaryConvertStrategy<FileVersion, FileVersionDTO> dictionaryConvertStrategy = new()
{
ConvertStrategy = fileVersionDTOConvertStrategy,
ReferenceDictionary = refDictinary,
TraceLogger = TraceLogger
};
var versionDTO = dictionaryConvertStrategy.ConvertTo(version as FileVersion);
return versionDTO;
}
private static string Serialize(object obj, IShiftTraceLogger logger)
{
var settings = new JsonSerializerSettings
{
Converters = new List<JsonConverter>
{
new FileVersionDTOJsonConverter(logger), // Add the specific converter
// Add other converters if needed
},
Formatting = Formatting.Indented,
PreserveReferencesHandling = PreserveReferencesHandling.All,
MissingMemberHandling = MissingMemberHandling.Ignore,
TypeNameHandling = TypeNameHandling.All,
NullValueHandling = NullValueHandling.Include
};
return JsonConvert.SerializeObject(obj, settings);
}
public void SaveFileAs(IProject project)
{
var tmpIsNew = project.IsNewFile;
var tmpFullFileName = project.FullFileName;
project.IsNewFile = true;
SaveFile(project);
if (project.IsNewFile == true)
{
project.IsNewFile = tmpIsNew;
project.FullFileName = tmpFullFileName;
}
}
}
}

View File

@@ -0,0 +1,10 @@
using StructureHelperCommon.Infrastructures.Interfaces;
using StructureHelperCommon.Models.Projects;
namespace DataAccess.Infrastructures
{
public interface IFileOpenLogic : ILogic
{
OpenProjectResult OpenFile();
}
}

View File

@@ -0,0 +1,16 @@
using StructureHelperCommon.Infrastructures.Interfaces;
using StructureHelperCommon.Models.Projects;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DataAccess.Infrastructures
{
public interface IFileSaveLogic : ILogic
{
void SaveFile(IProject project);
void SaveFileAs(IProject project);
}
}

View File

@@ -0,0 +1,18 @@
using StructureHelperCommon.Infrastructures.Interfaces;
using StructureHelperCommon.Models.Projects;
using StructureHelperCommon.Services.FileServices;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DataAccess.Infrastructures
{
public interface IProjectAccessLogic : ILogic
{
OpenProjectResult OpenProject();
void SaveProject(IProject project);
void SaveProjectAs(IProject project);
}
}

View File

@@ -0,0 +1,17 @@
using StructureHelperCommon.Models.Calculators;
using StructureHelperCommon.Models.Projects;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DataAccess.Infrastructures
{
public class OpenProjectResult : IResult
{
public bool IsValid { get; set; } = true;
public string? Description { get; set; } = string.Empty;
public IProject Project { get; set; }
}
}

View File

@@ -0,0 +1,47 @@
using StructureHelperCommon.Models;
using StructureHelperCommon.Models.Projects;
using StructureHelperCommon.Services.FileServices;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DataAccess.Infrastructures
{
public class ProjectAccessLogic : IProjectAccessLogic
{
private IFileOpenLogic openLogic;
private IFileSaveLogic saveLogic;
public IShiftTraceLogger? TraceLogger { get; set; }
public ProjectAccessLogic(IFileOpenLogic openLogic, IFileSaveLogic saveLogic)
{
this.openLogic = openLogic;
this.saveLogic = saveLogic;
}
public ProjectAccessLogic() : this(new FileOpenLogic(), new FileSaveLogic())
{
}
public OpenProjectResult OpenProject()
{
openLogic.TraceLogger = TraceLogger;
return openLogic.OpenFile();
}
public void SaveProject(IProject project)
{
saveLogic.TraceLogger = TraceLogger;
saveLogic.SaveFile(project);
}
public void SaveProjectAs(IProject project)
{
saveLogic.TraceLogger = TraceLogger;
saveLogic.SaveFileAs(project);
}
}
}

View File

@@ -1,95 +0,0 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using StructureHelperCommon.Models;
using System;
using System.Reflection;
namespace DataAccess.JsonConverters
{
public abstract class BaseConverter<T> : JsonConverter<T>
{
private IShiftTraceLogger traceLogger;
protected BaseConverter(IShiftTraceLogger logger)
{
traceLogger = logger;
}
public override void WriteJson(JsonWriter writer, T value, JsonSerializer serializer)
{
traceLogger.AddMessage($"Serializing {typeof(T).Name} (ID: {GetId(value)})");
// Use JsonSerializer's default behavior to handle attributes like [JsonIgnore] and [JsonProperty]
var jo = new JObject();
foreach (var prop in typeof(T).GetProperties())
{
if (!ShouldIgnoreProperty(prop))
{
string propertyName = GetPropertyName(prop);
var propValue = prop.GetValue(value);
jo.Add(propertyName, JToken.FromObject(propValue, serializer));
}
}
jo.WriteTo(writer);
}
// Helper method to check if a property should be ignored
private bool ShouldIgnoreProperty(PropertyInfo prop)
{
// Check for [JsonIgnore] attribute
var jsonIgnoreAttribute = prop.GetCustomAttribute<JsonIgnoreAttribute>();
return jsonIgnoreAttribute != null;
}
// Helper method to get the property name, considering [JsonProperty] and [JsonPropertyName] attributes
private string GetPropertyName(PropertyInfo prop)
{
// Check for [JsonProperty] attribute (for Newtonsoft.Json)
var jsonPropertyAttribute = prop.GetCustomAttribute<JsonPropertyAttribute>();
if (jsonPropertyAttribute != null)
{
return jsonPropertyAttribute.PropertyName;
}
// Check for [JsonPropertyName] attribute (for System.Text.Json compatibility)
var jsonPropertyNameAttribute = prop.GetCustomAttribute<System.Text.Json.Serialization.JsonPropertyNameAttribute>();
if (jsonPropertyNameAttribute != null)
{
return jsonPropertyNameAttribute.Name;
}
// Default to the property name if no attributes are found
return prop.Name;
}
public override T ReadJson(JsonReader reader, Type objectType, T existingValue, bool hasExistingValue, JsonSerializer serializer)
{
traceLogger.AddMessage($"Deserializing {typeof(T).Name}");
// Use JsonSerializer's default behavior to handle attributes during deserialization
JObject jo = JObject.Load(reader);
T obj = Activator.CreateInstance<T>();
foreach (var prop in typeof(T).GetProperties())
{
if (!ShouldIgnoreProperty(prop) && jo.TryGetValue(GetPropertyName(prop), out JToken value))
{
var propValue = value.ToObject(prop.PropertyType, serializer);
prop.SetValue(obj, propValue);
}
}
traceLogger.AddMessage($"Deserialized {typeof(T).Name} (ID: {GetId(obj)})");
return obj;
}
// Method to get the ID for logging purposes, assumes all classes have an 'Id' property of type Guid.
private Guid GetId(object obj)
{
var idProp = obj.GetType().GetProperty("Id");
return idProp != null ? (Guid)idProp.GetValue(obj) : Guid.Empty;
}
}
}

View File

@@ -0,0 +1,48 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using StructureHelperCommon.Models;
using System;
using System.Reflection;
namespace DataAccess.JsonConverters
{
public abstract class BaseJsonConverter<T> : JsonConverter<T>
{
private IWriteJsonLogic<T> writeJsonLogic;
private IReadJsonLogic<T> readJsonLogic;
public IShiftTraceLogger TraceLogger { get; set; }
protected BaseJsonConverter(IShiftTraceLogger logger, IWriteJsonLogic<T> writeJsonLogic, IReadJsonLogic<T> readJsonLogic)
{
this.writeJsonLogic = writeJsonLogic;
this.readJsonLogic = readJsonLogic;
TraceLogger = logger;
}
protected BaseJsonConverter(IShiftTraceLogger logger)
: this (logger,
new WriteJsonLogic<T>() { TraceLogger = logger},
new ReadJsonLogic<T>() { TraceLogger = logger})
{
}
public override void WriteJson(JsonWriter writer, T? value, JsonSerializer serializer)
{
writeJsonLogic.TraceLogger = TraceLogger;
writeJsonLogic.WriteJson(writer, value, serializer);
}
public override T ReadJson(JsonReader reader, Type objectType, T? existingValue, bool hasExistingValue, JsonSerializer serializer)
{
readJsonLogic.TraceLogger = TraceLogger;
return readJsonLogic.ReadJson(reader, objectType, existingValue, hasExistingValue, serializer);
}
}
}

View File

@@ -8,7 +8,7 @@ using System.Threading.Tasks;
namespace DataAccess.JsonConverters namespace DataAccess.JsonConverters
{ {
public class CrossSectionJsonConverter : BaseConverter<CrossSectionDTO> public class CrossSectionJsonConverter : BaseJsonConverter<CrossSectionDTO>
{ {
public CrossSectionJsonConverter(IShiftTraceLogger logger) : base(logger) public CrossSectionJsonConverter(IShiftTraceLogger logger) : base(logger)
{ {

View File

@@ -0,0 +1,17 @@
using DataAccess.DTOs;
using StructureHelperCommon.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DataAccess.JsonConverters
{
public class FileVersionDTOJsonConverter : BaseJsonConverter<FileVersionDTO>
{
public FileVersionDTOJsonConverter(IShiftTraceLogger logger) : base(logger)
{
}
}
}

View File

@@ -0,0 +1,22 @@
using StructureHelperCommon.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DataAccess.JsonConverters
{
/// <inheritdoc/>
public class GetIdFromObjectLogic : IGetIdFromObjectLogic
{
/// <inheritdoc/>
public IShiftTraceLogger? TraceLogger { get; set; }
/// <inheritdoc/>
public Guid GetId(object obj)
{
var idProp = obj.GetType().GetProperty("Id");
return idProp != null ? (Guid)idProp.GetValue(obj) : Guid.Empty;
}
}
}

View File

@@ -0,0 +1,38 @@
using Newtonsoft.Json;
using StructureHelperCommon.Infrastructures.Interfaces;
using StructureHelperCommon.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace DataAccess.JsonConverters
{
public class GetPropertyNameLogic : IGetPropertyNameLogic
{
public IShiftTraceLogger? TraceLogger { get; set; }
// Helper method to get the property name, considering [JsonProperty] and [JsonPropertyName] attributes
public string GetPropertyName(PropertyInfo prop)
{
// Check for [JsonProperty] attribute (for Newtonsoft.Json)
var jsonPropertyAttribute = prop.GetCustomAttribute<JsonPropertyAttribute>();
if (jsonPropertyAttribute != null)
{
return jsonPropertyAttribute.PropertyName;
}
// Check for [JsonPropertyName] attribute (for System.Text.Json compatibility)
var jsonPropertyNameAttribute = prop.GetCustomAttribute<System.Text.Json.Serialization.JsonPropertyNameAttribute>();
if (jsonPropertyNameAttribute != null)
{
return jsonPropertyNameAttribute.Name;
}
// Default to the property name if no attributes are found
return prop.Name;
}
}
}

View File

@@ -0,0 +1,12 @@
using StructureHelperCommon.Infrastructures.Interfaces;
namespace DataAccess.JsonConverters
{
/// <summary>
/// Logic to get the ID for logging purposes, assumes all classes have an 'Id' property of type Guid.
/// </summary>
public interface IGetIdFromObjectLogic : ILogic
{
Guid GetId(object obj);
}
}

View File

@@ -0,0 +1,13 @@
using StructureHelperCommon.Infrastructures.Interfaces;
using System.Reflection;
namespace DataAccess.JsonConverters
{
/// <summary>
/// Helper logic to get the property name, considering [JsonProperty] and [JsonPropertyName] attributes
/// </summary>
public interface IGetPropertyNameLogic : ILogic
{
string GetPropertyName(PropertyInfo prop);
}
}

View File

@@ -0,0 +1,23 @@
using Newtonsoft.Json;
using StructureHelperCommon.Infrastructures.Interfaces;
namespace DataAccess.JsonConverters
{
/// <summary>
/// Helper logic for JSON converter
/// </summary>
/// <typeparam name="T"></typeparam>
public interface IReadJsonLogic<T> : ILogic
{
/// <summary>
///
/// </summary>
/// <param name="reader"></param>
/// <param name="objectType"></param>
/// <param name="existingValue"></param>
/// <param name="hasExistingValue"></param>
/// <param name="serializer"></param>
/// <returns></returns>
T ReadJson(JsonReader reader, Type objectType, T existingValue, bool hasExistingValue, JsonSerializer serializer);
}
}

View File

@@ -0,0 +1,13 @@
using StructureHelperCommon.Infrastructures.Interfaces;
using System.Reflection;
namespace DataAccess.JsonConverters
{
/// <summary>
/// Helper logic to check if a property should be ignored
/// </summary>
public interface IShouldIgnorePropertyLogic : ILogic
{
bool ShouldIgnoreProperty(PropertyInfo prop);
}
}

View File

@@ -0,0 +1,10 @@
using Newtonsoft.Json;
using StructureHelperCommon.Infrastructures.Interfaces;
namespace DataAccess.JsonConverters
{
public interface IWriteJsonLogic<T> : ILogic
{
void WriteJson(JsonWriter writer, T value, JsonSerializer serializer);
}
}

View File

@@ -0,0 +1,56 @@
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using StructureHelperCommon.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DataAccess.JsonConverters
{
public class ReadJsonLogic<T> : IReadJsonLogic<T>
{
private IShouldIgnorePropertyLogic shouldIgnorePropertyLogic;
private IGetPropertyNameLogic getPropertyNameLogic;
private IGetIdFromObjectLogic getIdFromObjectLogic;
public IShiftTraceLogger? TraceLogger { get; set; }
public ReadJsonLogic(IShouldIgnorePropertyLogic shouldIgnorePropertyLogic,
IGetPropertyNameLogic getPropertyNameLogic,
IGetIdFromObjectLogic getIdFromObjectLogic)
{
this.shouldIgnorePropertyLogic = shouldIgnorePropertyLogic;
this.getPropertyNameLogic = getPropertyNameLogic;
this.getIdFromObjectLogic = getIdFromObjectLogic;
}
public ReadJsonLogic()
: this(new ShouldIgnorePropertyLogic(),
new GetPropertyNameLogic(),
new GetIdFromObjectLogic())
{
}
public T ReadJson(JsonReader reader, Type objectType, T existingValue, bool hasExistingValue, JsonSerializer serializer)
{
TraceLogger?.AddMessage($"Deserializing {typeof(T).Name}");
shouldIgnorePropertyLogic.TraceLogger = getPropertyNameLogic.TraceLogger = getIdFromObjectLogic.TraceLogger = TraceLogger;
// Use JsonSerializer's default behavior to handle attributes during deserialization
JObject jo = JObject.Load(reader);
T obj = Activator.CreateInstance<T>();
foreach (var prop in typeof(T).GetProperties())
{
if (! shouldIgnorePropertyLogic.ShouldIgnoreProperty(prop) && jo.TryGetValue(getPropertyNameLogic.GetPropertyName(prop), out JToken value))
{
var propValue = value.ToObject(prop.PropertyType, serializer);
prop.SetValue(obj, propValue);
}
}
TraceLogger?.AddMessage($"Deserialized {typeof(T).Name} (ID: {getIdFromObjectLogic.GetId(obj)})");
return obj;
}
}
}

View File

@@ -0,0 +1,22 @@
using Newtonsoft.Json;
using StructureHelperCommon.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace DataAccess.JsonConverters
{
public class ShouldIgnorePropertyLogic : IShouldIgnorePropertyLogic
{
public IShiftTraceLogger? TraceLogger { get; set; }
public bool ShouldIgnoreProperty(PropertyInfo prop)
{
// Check for [JsonIgnore] attribute
var jsonIgnoreAttribute = prop.GetCustomAttribute<JsonIgnoreAttribute>();
return jsonIgnoreAttribute != null;
}
}
}

View File

@@ -0,0 +1,54 @@
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using StructureHelperCommon.Infrastructures.Interfaces;
using StructureHelperCommon.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DataAccess.JsonConverters
{
public class WriteJsonLogic<T> : IWriteJsonLogic<T>
{
private IShouldIgnorePropertyLogic shouldIgnorePropertyLogic;
private IGetPropertyNameLogic getPropertyNameLogic;
private IGetIdFromObjectLogic getIdFromObjectLogic;
public IShiftTraceLogger? TraceLogger { get; set; }
public WriteJsonLogic(IShouldIgnorePropertyLogic shouldIgnorePropertyLogic,
IGetPropertyNameLogic getPropertyNameLogic,
IGetIdFromObjectLogic getIdFromObjectLogic)
{
this.shouldIgnorePropertyLogic = shouldIgnorePropertyLogic;
this.getPropertyNameLogic = getPropertyNameLogic;
this.getIdFromObjectLogic = getIdFromObjectLogic;
}
public WriteJsonLogic()
: this(new ShouldIgnorePropertyLogic(),
new GetPropertyNameLogic(),
new GetIdFromObjectLogic())
{
}
public void WriteJson(JsonWriter writer, T value, JsonSerializer serializer)
{
TraceLogger?.AddMessage($"Serializing {typeof(T).Name} (ID: {getIdFromObjectLogic.GetId(value)})");
shouldIgnorePropertyLogic.TraceLogger = getPropertyNameLogic.TraceLogger = getIdFromObjectLogic.TraceLogger = TraceLogger;
// Use JsonSerializer's default behavior to handle attributes like [JsonIgnore] and [JsonProperty]
var jo = new JObject();
foreach (var prop in typeof(T).GetProperties())
{
if (!shouldIgnorePropertyLogic.ShouldIgnoreProperty(prop))
{
string propertyName = getPropertyNameLogic.GetPropertyName(prop);
var propValue = prop.GetValue(value);
jo.Add(propertyName, JToken.FromObject(propValue, serializer));
}
}
jo.WriteTo(writer);
}
}
}

View File

@@ -54,16 +54,17 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Autofac" Version="6.5.0" /> <PackageReference Include="Autofac" Version="8.1.0" />
<PackageReference Include="LiveCharts.Wpf" Version="0.9.7" /> <PackageReference Include="LiveCharts.Wpf" Version="0.9.7" />
<PackageReference Include="LiveCharts.Wpf.Core" Version="0.9.8" /> <PackageReference Include="LiveCharts.Wpf.Core" Version="0.9.8" />
<PackageReference Include="LiveCharts.Wpf.NetCore3" Version="0.9.7" /> <PackageReference Include="LiveCharts.Wpf.NetCore3" Version="0.9.8" />
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.39" /> <PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.122" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="System.Windows.Interactivity.WPF" Version="2.0.20525" /> <PackageReference Include="System.Windows.Interactivity.WPF" Version="2.0.20525" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\DataAccess\DataAccess.csproj" />
<ProjectReference Include="..\FieldVisualizer\FieldVisualizer.csproj" /> <ProjectReference Include="..\FieldVisualizer\FieldVisualizer.csproj" />
<ProjectReference Include="..\StructureHelperCommon\StructureHelperCommon.csproj" /> <ProjectReference Include="..\StructureHelperCommon\StructureHelperCommon.csproj" />
<ProjectReference Include="..\StructureHelperLogics\StructureHelperLogics.csproj" /> <ProjectReference Include="..\StructureHelperLogics\StructureHelperLogics.csproj" />

View File

@@ -6,7 +6,7 @@
xmlns:local="clr-namespace:StructureHelper.Windows.CalculationWindows.ProgressViews" xmlns:local="clr-namespace:StructureHelper.Windows.CalculationWindows.ProgressViews"
d:DataContext="{d:DesignInstance local:TraceDocumentVM}" d:DataContext="{d:DesignInstance local:TraceDocumentVM}"
mc:Ignorable="d" mc:Ignorable="d"
Title="Trace Document Viewer" Height="450" Width="800" MinHeight="400" MinWidth="600" WindowStartupLocation="CenterScreen" ShowInTaskbar="False"> Title="Trace Document Viewer" Height="450" Width="800" MinHeight="400" MinWidth="600" WindowStartupLocation="CenterScreen">
<Grid> <Grid>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/>

View File

@@ -18,6 +18,8 @@ namespace StructureHelper.Windows.CalculationWindows.ProgressViews
this.viewModel.DocumentReader = this.DocumentReader; this.viewModel.DocumentReader = this.DocumentReader;
this.viewModel.Show(); this.viewModel.Show();
} }
public TraceDocumentView(ITraceLogger traceLogger) : this (traceLogger.TraceLoggerEntries) { }
public TraceDocumentView(IEnumerable<ITraceLoggerEntry> loggerEntries) : this(new TraceDocumentVM(loggerEntries)) { } public TraceDocumentView(IEnumerable<ITraceLoggerEntry> loggerEntries) : this(new TraceDocumentVM(loggerEntries)) { }
} }
} }

View File

@@ -1,5 +1,7 @@
using StructureHelper.Infrastructure; using StructureHelper.Infrastructure;
using StructureHelper.Windows.MainWindow.Analyses; using StructureHelper.Windows.MainWindow.Analyses;
using StructureHelperCommon.Infrastructures.Settings;
using StructureHelperCommon.Models.Analyses;
using StructureHelperLogic.Models.Analyses; using StructureHelperLogic.Models.Analyses;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@@ -21,7 +23,6 @@ namespace StructureHelper.Windows.MainWindow
public IVisualAnalysis? SelectedAnalysis { get; set; } public IVisualAnalysis? SelectedAnalysis { get; set; }
public List<IVisualAnalysis> AnalysesList { get; }
public ObservableCollection<IVisualAnalysis> FilteredAnalyses { get; } public ObservableCollection<IVisualAnalysis> FilteredAnalyses { get; }
public RelayCommand AddAnalysisCommand public RelayCommand AddAnalysisCommand
{ {
@@ -74,13 +75,12 @@ namespace StructureHelper.Windows.MainWindow
public AnalysesLogic() public AnalysesLogic()
{ {
AnalysesList = new();
FilteredAnalyses = new(); FilteredAnalyses = new();
} }
public void Refresh() public void Refresh()
{ {
FilteredAnalyses.Clear(); FilteredAnalyses.Clear();
var analysesList = AnalysesList.ToList(); var analysesList = ProgramSetting.CurrentProject.VisualAnalyses.ToList();
foreach (var analysis in analysesList) foreach (var analysis in analysesList)
{ {
FilteredAnalyses.Add(analysis); FilteredAnalyses.Add(analysis);
@@ -108,7 +108,7 @@ namespace StructureHelper.Windows.MainWindow
var dialogResult = MessageBox.Show("Delete analysis?", "Please, confirm deleting", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); var dialogResult = MessageBox.Show("Delete analysis?", "Please, confirm deleting", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
if (dialogResult == DialogResult.Yes) if (dialogResult == DialogResult.Yes)
{ {
AnalysesList.Remove(SelectedAnalysis); ProgramSetting.CurrentProject.VisualAnalyses.Remove(SelectedAnalysis);
} }
} }
} }
@@ -122,7 +122,7 @@ namespace StructureHelper.Windows.MainWindow
analysis.Name = "New NDM Analysis"; analysis.Name = "New NDM Analysis";
analysis.Tags = "#New group"; analysis.Tags = "#New group";
var visualAnalysis = new VisualAnalysis(analysis); var visualAnalysis = new VisualAnalysis(analysis);
AnalysesList.Add(visualAnalysis); ProgramSetting.CurrentProject.VisualAnalyses.Add(visualAnalysis);
} }
} }
} }

View File

@@ -0,0 +1,147 @@
using DataAccess.Infrastructures;
using StructureHelper.Infrastructure;
using StructureHelper.Windows.CalculationWindows.ProgressViews;
using StructureHelperCommon.Infrastructures.Settings;
using StructureHelperCommon.Models;
using StructureHelperCommon.Models.Projects;
using System;
using System.Linq;
using System.Windows.Forms;
using System.Windows.Input;
namespace StructureHelper.Windows.MainWindow
{
public class FileLogic : ViewModelBase
{
private ICommand fileOpen;
private ICommand fileSave;
private IShiftTraceLogger traceLogger;
private RelayCommand fileNew;
private RelayCommand fileClose;
private IProjectAccessLogic projectAccessLogic;
private RelayCommand fileSaveAs;
public FileLogic(IProjectAccessLogic projectAccessLogic)
{
this.projectAccessLogic = projectAccessLogic;
}
public FileLogic() : this(new ProjectAccessLogic())
{
}
public ICommand FileOpen => fileOpen ??= new RelayCommand(obj => OpenFile());
public ICommand FileNew => fileNew ??= new RelayCommand(obj => NewFile());
public ICommand ProgramExit => fileNew ??= new RelayCommand(obj => ExitProgram());
public ICommand FileClose => fileClose ??= new RelayCommand(obj => CloseFile());
public ICommand FileSave => fileSave ??= new RelayCommand(obj => SaveFile());
public ICommand FileSaveAs => fileSaveAs ??= new RelayCommand(obj => SaveAsFile());
public void NewFile()
{
var closeResult = CloseFile();
if (closeResult == false)
{
return;
}
var newProject = CreateNewFile();
ProgramSetting.Projects.Add(newProject);
}
public IProject CreateNewFile()
{
var newProject = new Project()
{
IsNewFile = true,
IsActual = true
};
ProgramSetting.Projects.Add(newProject);
return newProject;
}
private void SaveAsFile()
{
var project = ProgramSetting.CurrentProject;
traceLogger = new ShiftTraceLogger();
projectAccessLogic.TraceLogger = traceLogger;
projectAccessLogic.SaveProjectAs(project);
ShowEntries();
}
private void ExitProgram()
{
foreach (var project in ProgramSetting.Projects)
{
CloseFile(project);
}
}
private bool CloseFile()
{
var project = ProgramSetting.CurrentProject;
if (project is null) { return false; }
return CloseFile(project);
}
private bool CloseFile(IProject project)
{
if (project.IsActual == true & project.IsNewFile == false)
{
ProgramSetting.Projects.Remove(project);
return true;
}
var dialogResult = MessageBox.Show($"Save file?", $"File {project.FullFileName} is not saved", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning);
if (dialogResult == DialogResult.Yes)
{
SaveFile(project);
}
if (dialogResult == DialogResult.Cancel)
{
return false;
}
project.IsActual = true;
project.IsNewFile = false;
CloseFile(project);
return true;
}
private void SaveFile()
{
var project = ProgramSetting.CurrentProject;
SaveFile(project);
}
private void SaveFile(IProject project)
{
traceLogger = new ShiftTraceLogger();
projectAccessLogic.TraceLogger = traceLogger;
projectAccessLogic.SaveProject(project);
ShowEntries();
}
private void OpenFile()
{
var currentProject = ProgramSetting.CurrentProject;
var closeResult = CloseFile();
if (closeResult == false)
{
return;
}
traceLogger = new ShiftTraceLogger();
projectAccessLogic.TraceLogger = traceLogger;
var result = projectAccessLogic.OpenProject();
if (result.IsValid == true)
{
ProgramSetting.Projects.Add(result.Project);
}
else
{
ProgramSetting.Projects.Add(currentProject);
}
ShowEntries();
}
private void ShowEntries()
{
var filteredEntries = traceLogger.TraceLoggerEntries.Where(x => x.Priority <= 300);
if (filteredEntries.Any())
{
var wnd = new TraceDocumentView(traceLogger);
wnd.ShowDialog();
}
}
}
}

View File

@@ -1,15 +0,0 @@
using StructureHelperCommon.Models.Analyses;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelper.Windows.MainWindow.Analyses
{
public interface IVisualAnalysis
{
IAnalysis Analysis {get;set;}
void Run();
}
}

View File

@@ -2,22 +2,26 @@
using StructureHelperCommon.Models.Analyses; using StructureHelperCommon.Models.Analyses;
using StructureHelperLogics.Models.CrossSections; using StructureHelperLogics.Models.CrossSections;
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelper.Windows.MainWindow.Analyses namespace StructureHelper.Windows.MainWindow.Analyses
{ {
public class VisualAnalysis : IVisualAnalysis public class VisualAnalysis : IVisualAnalysis
{ {
public Guid Id { get; }
public IAnalysis Analysis { get; set; } public IAnalysis Analysis { get; set; }
public VisualAnalysis(IAnalysis analysis)
public VisualAnalysis(Guid id, IAnalysis analysis)
{ {
Id = id;
Analysis = analysis; Analysis = analysis;
} }
public VisualAnalysis(IAnalysis analysis) : this (Guid.NewGuid(), analysis)
{
}
public void Run() public void Run()
{ {
var version = Analysis.VersionProcessor.GetCurrentVersion(); var version = Analysis.VersionProcessor.GetCurrentVersion();

View File

@@ -9,16 +9,24 @@
Title="Analyses Manager" Height="450" Width="800" MinHeight="400" MinWidth="600" WindowStartupLocation="CenterScreen"> Title="Analyses Manager" Height="450" Width="800" MinHeight="400" MinWidth="600" WindowStartupLocation="CenterScreen">
<Grid> <Grid>
<DockPanel> <DockPanel>
<Menu DockPanel.Dock="Top">
<MenuItem Header="File" DataContext="{Binding FileLogic}">
<MenuItem Header="New" Command="{Binding FileNew}"/>
<MenuItem Header="Open" Command="{Binding FileOpen}"/>
<MenuItem Header="Save" Command="{Binding FileSave}"/>
<MenuItem Header="SaveAs" Command="{Binding FileSaveAs}"/>
</MenuItem>
</Menu>
<ToolBarTray DockPanel.Dock="Top"> <ToolBarTray DockPanel.Dock="Top">
<ToolBar DataContext="{Binding FileLogic}" ToolTip="File"> <ToolBar DataContext="{Binding FileLogic}" ToolTip="File">
<Button Style="{StaticResource ToolButton}" <Button Style="{StaticResource ToolButton}"
Command="{Binding Add}" ToolTip="Open file"> Command="{Binding FileOpen}" ToolTip="Open file">
<Viewbox> <Viewbox>
<ContentControl ContentTemplate="{DynamicResource FileOpen}"/> <ContentControl ContentTemplate="{DynamicResource FileOpen}"/>
</Viewbox> </Viewbox>
</Button> </Button>
<Button Style="{StaticResource ToolButton}" <Button Style="{StaticResource ToolButton}"
Command="{Binding Add}" ToolTip="Save file"> Command="{Binding FileSave}" ToolTip="Save file">
<Viewbox> <Viewbox>
<ContentControl ContentTemplate="{DynamicResource FileSave}"/> <ContentControl ContentTemplate="{DynamicResource FileSave}"/>
</Viewbox> </Viewbox>

View File

@@ -16,6 +16,7 @@ namespace StructureHelper.Windows.MainWindow
public AnalysesManagerViewModel() public AnalysesManagerViewModel()
{ {
FileLogic = new(); FileLogic = new();
FileLogic.CreateNewFile();
DiagramLogic = new(); DiagramLogic = new();
AnalysesLogic = new(); AnalysesLogic = new();
} }

View File

@@ -1,19 +0,0 @@
using StructureHelper.Infrastructure;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
namespace StructureHelper.Windows.MainWindow
{
public class FileLogic : ViewModelBase
{
private ICommand fileOpen;
private ICommand fileSave;
public ICommand FileOpen => fileOpen;
public ICommand FileSave => fileSave;
}
}

View File

@@ -0,0 +1,71 @@
using StructureHelperCommon.Infrastructures.Exceptions;
using StructureHelperCommon.Models;
using StructureHelperCommon.Models.Projects;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media;
namespace StructureHelperCommon.Infrastructures.Interfaces
{
public class DictionaryConvertStrategy<T, V> : IConvertStrategy<T, V>
where T : ISaveable
where V : ISaveable
{
public IShiftTraceLogger? TraceLogger { get; set; }
public IConvertStrategy<T,V> ConvertStrategy { get; set; }
public Dictionary<(Guid id, Type type), ISaveable> ReferenceDictionary { get; set; }
public T ConvertFrom(V source)
{
ICheckInputData();
T val;
var key = (source.Id, typeof(T));
if (ReferenceDictionary.ContainsKey(key))
{
ISaveable existValue;
ReferenceDictionary.TryGetValue(key, out existValue);
val = (T)existValue;
TraceLogger?.AddMessage($"Value of {typeof(T)} (Id = {existValue.Id}) exists already", TraceLogStatuses.Debug);
}
else
{
val = ConvertStrategy.ConvertFrom(source);
ReferenceDictionary.Add(key, val);
TraceLogger?.AddMessage($"New value of {typeof(T)} (Id = {val.Id}) was added to dictionary", TraceLogStatuses.Debug);
}
return val;
}
public V ConvertTo(T source)
{
ICheckInputData();
V val;
var key = (source.Id, typeof(V));
if (ReferenceDictionary.ContainsKey(key))
{
ISaveable existValue;
ReferenceDictionary.TryGetValue(key, out existValue);
val = (V)existValue;
TraceLogger?.AddMessage($"Value of {typeof(V)} (Id = {existValue.Id}) exists already", TraceLogStatuses.Debug);
}
else
{
val = ConvertStrategy.ConvertTo(source);
ReferenceDictionary.Add(key, val);
TraceLogger?.AddMessage($"New value of {typeof(V)} (Id = {val.Id}) was added to dictionary", TraceLogStatuses.Debug);
}
return val;
}
private void ICheckInputData()
{
if(ReferenceDictionary is null)
{
string errorString = ErrorStrings.ParameterIsNull + ": Reference Dictionary";
TraceLogger?.AddMessage(errorString, TraceLogStatuses.Error);
throw new StructureHelperException(errorString);
}
}
}
}

View File

@@ -0,0 +1,18 @@
using StructureHelperCommon.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelperCommon.Infrastructures.Interfaces
{
public interface IConvertStrategy<T,V>
where T :ISaveable
where V :ISaveable
{
IShiftTraceLogger TraceLogger { get; set; }
V ConvertTo(T source);
T ConvertFrom(V source);
}
}

View File

@@ -3,7 +3,9 @@ using StructureHelperCommon.Models.Codes;
using StructureHelperCommon.Models.Codes.Factories; using StructureHelperCommon.Models.Codes.Factories;
using StructureHelperCommon.Models.Materials; using StructureHelperCommon.Models.Materials;
using StructureHelperCommon.Models.Materials.Libraries; using StructureHelperCommon.Models.Materials.Libraries;
using StructureHelperCommon.Models.Projects;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.Design.Serialization;
using System.Linq; using System.Linq;
using System.Windows.Documents; using System.Windows.Documents;
using System.Windows.Navigation; using System.Windows.Navigation;
@@ -55,7 +57,15 @@ namespace StructureHelperCommon.Infrastructures.Settings
return materialRepository; return materialRepository;
} }
} }
public static List<IProject> Projects { get; } = new();
public static IProject CurrentProject
{
get
{
if (Projects.Any()) { return Projects[0]; }
return null;
}
}
public static List<IMaterialLogic> MaterialLogics public static List<IMaterialLogic> MaterialLogics
{ {
get get
@@ -64,5 +74,21 @@ namespace StructureHelperCommon.Infrastructures.Settings
return materialLogics; return materialLogics;
} }
} }
public static void SetCurrentProjectToNotActual()
{
if (CurrentProject is null)
{
return;
}
CurrentProject.IsActual = false;
}
public static IFileVersion GetCurrentFileVersion()
{
return new FileVersion()
{
VersionNumber = 1,
SubVersionNumber = 0
};
}
} }
} }

View File

@@ -0,0 +1,16 @@
using StructureHelperCommon.Infrastructures.Interfaces;
using StructureHelperCommon.Models.Analyses;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelperCommon.Models.Analyses
{
public interface IVisualAnalysis : ISaveable
{
IAnalysis Analysis {get;set;}
void Run();
}
}

View File

@@ -0,0 +1,47 @@
using StructureHelperCommon.Infrastructures.Exceptions;
using StructureHelperCommon.Infrastructures.Interfaces;
using StructureHelperCommon.Infrastructures.Settings;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Documents;
namespace StructureHelperCommon.Models.Projects
{
public class CheckFileVersionLogic : ICheckLogic
{
private const string checkIsGood = "Checking is good";
public IFileVersion? FileVersion { get; set; }
public string CheckResult { get; private set; } = string.Empty;
public IShiftTraceLogger? TraceLogger { get; set; }
public bool Check()
{
if (FileVersion is null)
{
throw new StructureHelperException(ErrorStrings.ParameterIsNull + ": File Version");
}
var currentVersion = ProgramSetting.GetCurrentFileVersion();
if (currentVersion.VersionNumber < FileVersion.VersionNumber)
{
string message = $"File version {FileVersion.VersionNumber} is bigger than suitable version {currentVersion.VersionNumber}";
TraceLogger?.AddMessage(message, TraceLogStatuses.Error);
CheckResult += message;
return false;
}
if (currentVersion.SubVersionNumber < FileVersion.SubVersionNumber)
{
string message = $"File version {FileVersion.VersionNumber}.{FileVersion.SubVersionNumber} is bigger than suitable version {currentVersion.VersionNumber}.{currentVersion.VersionNumber}";
TraceLogger?.AddMessage(message, TraceLogStatuses.Error);
CheckResult += message;
return false;
}
CheckResult += checkIsGood;
return true;
}
}
}

View File

@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelperCommon.Models.Projects
{
public class FileVersion : IFileVersion
{
public Guid Id { get; }
public int VersionNumber { get; set; }
public int SubVersionNumber { get; set; }
public FileVersion(Guid id)
{
Id = id;
}
public FileVersion() : this(Guid.NewGuid())
{
}
}
}

View File

@@ -0,0 +1,21 @@
using StructureHelperCommon.Infrastructures.Interfaces;
using StructureHelperCommon.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelperCommon.Models.Projects
{
public class FileVersionUpdateStrategy : IUpdateStrategy<IFileVersion>
{
public void Update(IFileVersion targetObject, IFileVersion sourceObject)
{
CheckObject.IsNull(targetObject, sourceObject);
if (ReferenceEquals(targetObject, sourceObject)) { return; };
targetObject.VersionNumber = sourceObject.VersionNumber;
targetObject.SubVersionNumber = sourceObject.SubVersionNumber;
}
}
}

View File

@@ -0,0 +1,15 @@
using StructureHelperCommon.Infrastructures.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelperCommon.Models.Projects
{
public interface IFileVersion : ISaveable
{
int VersionNumber { get; set; }
int SubVersionNumber { get; set; }
}
}

View File

@@ -0,0 +1,19 @@
using StructureHelperCommon.Infrastructures.Interfaces;
using StructureHelperCommon.Models.Analyses;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelperCommon.Models.Projects
{
public interface IProject : ISaveable
{
string FullFileName { get; set; }
string FileName { get; }
bool IsNewFile { get; set; }
bool IsActual { get; set; }
List<IVisualAnalysis> VisualAnalyses { get;}
}
}

View File

@@ -0,0 +1,31 @@
using StructureHelperCommon.Infrastructures.Interfaces;
using StructureHelperCommon.Models.Analyses;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelperCommon.Models.Projects
{
public class Project : IProject
{
public Guid Id { get; }
public string FullFileName { get; set; } = string.Empty;
public bool IsActual { get; set; } = true;
public List<IVisualAnalysis> VisualAnalyses { get; } = new();
public bool IsNewFile { get; set; } = true;
public string FileName => Path.GetFileName(FullFileName);
public Project(Guid id)
{
Id = id;
}
public Project() : this(Guid.NewGuid())
{
}
}
}

View File

@@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace DataAccess.FileDialogs
{
public class FileDialogOpener
{
public void OpenFileAndRead()
{
//// Create an instance of OpenFileDialog
//using OpenFileDialog openFileDialog = new();
//// Set filter options and filter index
//openFileDialog.Filter = "Text Files (*.txt)|*.txt|All Files (*.*)|*.*";
//openFileDialog.FilterIndex = 1;
//openFileDialog.Multiselect = false; // Set to true if you want to allow multiple file selection
//openFileDialog.Title = "Select a File";
//// Show the dialog and get result
//if (openFileDialog.ShowDialog() == DialogResult.OK)
//{
// // Get the path of the selected file
// string selectedFilePath = openFileDialog.FileName;
// // Read the content of the file
// try
// {
// string fileContent = File.ReadAllText(selectedFilePath);
// Console.WriteLine($"File Content of '{selectedFilePath}':");
// Console.WriteLine(fileContent);
// }
// catch (IOException ex)
// {
// Console.WriteLine($"An error occurred while reading the file: {ex.Message}");
// }
//}
//else
//{
// Console.WriteLine("File selection was cancelled.");
//}
}
}
}

View File

@@ -0,0 +1,54 @@
using StructureHelperCommon.Infrastructures.Exceptions;
using StructureHelperCommon.Infrastructures.Interfaces;
using StructureHelperCommon.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace StructureHelperCommon.Services.FileServices
{
public class FileDialogSaver : IFileDialogSaver
{
private const string saveCanceledByUser = "Saving was canceled by user";
SaveFileResult result;
public SaveDialogInputData? InputData { get; set; }
public IShiftTraceLogger? TraceLogger { get; set; }
public SaveFileResult SaveFile()
{
CheckInput();
result = new();
using SaveFileDialog saveFileDialog = new();
saveFileDialog.Filter = InputData.FilterString;
saveFileDialog.InitialDirectory = InputData.InitialDirectory;
saveFileDialog.FilterIndex = InputData.FilterIndex;
saveFileDialog.CheckFileExists = InputData.CheckFileExist;
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
TraceLogger?.AddMessage($"User selected file {saveFileDialog.FileName}", TraceLogStatuses.Debug);
result.FileName = saveFileDialog.FileName;
return result;
}
else
{
TraceLogger?.AddMessage(saveCanceledByUser);
result.IsValid = false;
result.Description += saveCanceledByUser;
return result;
}
}
private void CheckInput()
{
if (InputData is null)
{
string errorString = ErrorStrings.ParameterIsNull + ": Input Data";
TraceLogger?.AddMessage(errorString, TraceLogStatuses.Error);
throw new StructureHelperException(errorString);
}
}
}
}

View File

@@ -0,0 +1,79 @@
using System;
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using StructureHelperCommon.Models;
using StructureHelperCommon.Infrastructures.Exceptions;
namespace StructureHelperCommon.Services.FileServices
{
public class FileOpener : IFileDialogOpener
{
private const string fileSelectionWasCanceled = "File selection was cancelled by user";
OpenFileResult? result;
IShiftTraceLogger? traceLogger;
public OpenFileInputData? InputData { get; private set; }
public FileOpener(OpenFileInputData inputData)
{
InputData = inputData;
}
public OpenFileResult OpenFile()
{
PrepareNewResult();
CheckInputData();
traceLogger = InputData.TraceLogger;
ShowOpenFileDialog();
return result;
}
private void ShowOpenFileDialog()
{
using (OpenFileDialog openFileDialog = new OpenFileDialog())
{
// Set filter options and filter index
openFileDialog.Filter = InputData.FilterString;
openFileDialog.FilterIndex = InputData.FilterIndex;
openFileDialog.Multiselect = InputData.MultiSelect;
openFileDialog.Title = InputData.Title;
// Show the dialog and get result
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
// Get the path of the selected file
string selectedFilePath = openFileDialog.FileName;
traceLogger?.AddMessage($"File {selectedFilePath} is selected by user", TraceLogStatuses.Debug);
result.FilePath = selectedFilePath;
}
else
{
result.IsValid = false;
result.Description = fileSelectionWasCanceled;
traceLogger?.AddMessage(fileSelectionWasCanceled, TraceLogStatuses.Debug);
Console.WriteLine(fileSelectionWasCanceled);
}
}
}
private void CheckInputData()
{
if (InputData is null)
{
result.IsValid = false;
string message = ErrorStrings.ParameterIsNull + ": Input Data";
result.Description = message;
throw new StructureHelperException(message);
}
}
private void PrepareNewResult()
{
result = new()
{
IsValid = true
};
}
}
}

View File

@@ -0,0 +1,9 @@
namespace StructureHelperCommon.Services.FileServices
{
public interface IFileDialogOpener
{
OpenFileInputData? InputData { get; }
OpenFileResult OpenFile();
}
}

View File

@@ -0,0 +1,9 @@
using StructureHelperCommon.Infrastructures.Interfaces;
namespace StructureHelperCommon.Services.FileServices
{
public interface IFileDialogSaver : ILogic
{
SaveFileResult SaveFile();
}
}

View File

@@ -0,0 +1,19 @@
using StructureHelperCommon.Models;
using StructureHelperCommon.Models.Calculators;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelperCommon.Services.FileServices
{
public class OpenFileInputData : IInputData
{
public IShiftTraceLogger? TraceLogger { get; set; }
public string FilterString { get; set; } = string.Empty;
public int FilterIndex { get; set; } = 1;
public bool MultiSelect { get; set; } = false;
public string Title { get; set; } = "Select a file";
}
}

View File

@@ -0,0 +1,16 @@
using StructureHelperCommon.Models.Calculators;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelperCommon.Services.FileServices
{
public class OpenFileResult : IResult
{
public bool IsValid { get; set; }
public string? Description { get; set; }
public string FilePath { get; set; } = string.Empty;
}
}

View File

@@ -0,0 +1,17 @@
using StructureHelperCommon.Models.Calculators;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelperCommon.Services.FileServices
{
public class SaveDialogInputData : IInputData
{
public string InitialDirectory { get; set; }
public int FilterIndex { get; set; } = 1;
public string FilterString { get; set; } = string.Empty;
public bool CheckFileExist { get; set; } = false;
}
}

View File

@@ -0,0 +1,16 @@
using StructureHelperCommon.Models.Calculators;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelperCommon.Services.FileServices
{
public class SaveFileResult : IResult
{
public bool IsValid { get; set; } = true;
public string? Description { get; set; } = string.Empty;
public string FileName { get; set; } = string.Empty;
}
}

View File

@@ -10,7 +10,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="NLog" Version="5.2.8" /> <PackageReference Include="NLog" Version="5.3.3" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -7,83 +7,83 @@ namespace StructureHelperLogics.Models.Storages
{ {
public class FileStorageManager //public class FileStorageManager
{ //{
private readonly Dictionary<Guid, OpenedFile> _openedFiles = new Dictionary<Guid, OpenedFile>(); // private readonly Dictionary<Guid, OpenedFile> _openedFiles = new Dictionary<Guid, OpenedFile>();
public void OpenFile() // public void OpenFile()
{ // {
using (OpenFileDialog openFileDialog = new OpenFileDialog()) // using (OpenFileDialog openFileDialog = new OpenFileDialog())
{ // {
openFileDialog.Filter = "Text Files (*.txt)|*.txt|All Files (*.*)|*.*"; // openFileDialog.Filter = "Text Files (*.txt)|*.txt|All Files (*.*)|*.*";
openFileDialog.Multiselect = true; // openFileDialog.Multiselect = true;
openFileDialog.Title = "Select Files"; // openFileDialog.Title = "Select Files";
if (openFileDialog.ShowDialog() == DialogResult.OK) // if (openFileDialog.ShowDialog() == DialogResult.OK)
{ // {
foreach (var filePath in openFileDialog.FileNames) // foreach (var filePath in openFileDialog.FileNames)
{ // {
var fileId = Guid.NewGuid(); // var fileId = Guid.NewGuid();
var openedFile = new OpenedFile(fileId, filePath); // var openedFile = new OpenedFile(fileId, filePath);
_openedFiles[fileId] = openedFile; // _openedFiles[fileId] = openedFile;
Console.WriteLine($"File '{openedFile.FilePath}' opened with ID: {fileId}"); // Console.WriteLine($"File '{openedFile.FilePath}' opened with ID: {fileId}");
} // }
} // }
} // }
} // }
public OpenedFile GetFile(Guid fileId) // public OpenedFile GetFile(Guid fileId)
{ // {
if (_openedFiles.TryGetValue(fileId, out var openedFile)) // if (_openedFiles.TryGetValue(fileId, out var openedFile))
{ // {
return openedFile; // return openedFile;
} // }
throw new KeyNotFoundException("File not found."); // throw new KeyNotFoundException("File not found.");
} // }
public void CloseFile(Guid fileId) // public void CloseFile(Guid fileId)
{ // {
if (_openedFiles.ContainsKey(fileId)) // if (_openedFiles.ContainsKey(fileId))
{ // {
_openedFiles.Remove(fileId); // _openedFiles.Remove(fileId);
Console.WriteLine($"File with ID: {fileId} has been closed."); // Console.WriteLine($"File with ID: {fileId} has been closed.");
} // }
else // else
{ // {
throw new KeyNotFoundException("File not found."); // throw new KeyNotFoundException("File not found.");
} // }
} // }
public void AddRelatedObjectToFile(Guid fileId, FileRelatedObject relatedObject) // //public void AddRelatedObjectToFile(Guid fileId, FileRelatedObject relatedObject)
{ // //{
var openedFile = GetFile(fileId); // // var openedFile = GetFile(fileId);
openedFile.AddRelatedObject(relatedObject); // // openedFile.AddRelatedObject(relatedObject);
Console.WriteLine($"Added related object to file ID: {fileId}, Related Object: {relatedObject}"); // // Console.WriteLine($"Added related object to file ID: {fileId}, Related Object: {relatedObject}");
} // //}
public FileRelatedObject GetRelatedObjectFromFile(Guid fileId, Guid objectId) // //public FileRelatedObject GetRelatedObjectFromFile(Guid fileId, Guid objectId)
{ // //{
var openedFile = GetFile(fileId); // // var openedFile = GetFile(fileId);
return openedFile.GetRelatedObject(objectId); // // return openedFile.GetRelatedObject(objectId);
} // //}
public void RemoveRelatedObjectFromFile(Guid fileId, Guid objectId) // public void RemoveRelatedObjectFromFile(Guid fileId, Guid objectId)
{ // {
var openedFile = GetFile(fileId); // var openedFile = GetFile(fileId);
openedFile.RemoveRelatedObject(objectId); // openedFile.RemoveRelatedObject(objectId);
Console.WriteLine($"Removed related object with ID: {objectId} from file ID: {fileId}"); // Console.WriteLine($"Removed related object with ID: {objectId} from file ID: {fileId}");
} // }
public void ListOpenedFiles() // public void ListOpenedFiles()
{ // {
foreach (var file in _openedFiles.Values) // foreach (var file in _openedFiles.Values)
{ // {
Console.WriteLine($"File ID: {file.Id}, Path: {file.FilePath}, Related Objects Count: {file.RelatedObjects.Count}"); // Console.WriteLine($"File ID: {file.Id}, Path: {file.FilePath}, Related Objects Count: {file.RelatedObjects.Count}");
} // }
} // }
} //}
} }

View File

@@ -7,78 +7,78 @@ using System.Threading.Tasks;
namespace StructureHelperLogics.Models.Storages namespace StructureHelperLogics.Models.Storages
{ {
public class OpenedFile //public class OpenedFile
{ //{
public Guid Id { get; } // public Guid Id { get; }
public string FilePath { get; } // public string FilePath { get; }
public List<ISaveable> RelatedObjects { get; } // List of related objects // public List<ISaveable> RelatedObjects { get; } // List of related objects
public OpenedFile(Guid id, string filePath) // public OpenedFile(Guid id, string filePath)
{ // {
Id = id; // Id = id;
FilePath = filePath; // FilePath = filePath;
RelatedObjects = new List<ISaveable>(); // RelatedObjects = new List<ISaveable>();
} // }
public void AddRelatedObject(ISaveable relatedObject) // public void AddRelatedObject(ISaveable relatedObject)
{ // {
RelatedObjects.Add(relatedObject); // RelatedObjects.Add(relatedObject);
} // }
public void RemoveRelatedObject(Guid objectId) // public void RemoveRelatedObject(Guid objectId)
{ // {
RelatedObjects.RemoveAll(o => o.Id == objectId); // RelatedObjects.RemoveAll(o => o.Id == objectId);
} // }
public ISaveable GetRelatedObject(Guid objectId) // public ISaveable GetRelatedObject(Guid objectId)
{ // {
return RelatedObjects.Find(o => o.Id == objectId); // return RelatedObjects.Find(o => o.Id == objectId);
} // }
} //}
class Program //class Program
{ //{
[STAThread] // Required for OpenFileDialog // [STAThread] // Required for OpenFileDialog
static void Main() // static void Main()
{ // {
var fileStorageManager = new FileStorageManager(); // var fileStorageManager = new FileStorageManager();
// Open files and add them to the storage // // Open files and add them to the storage
fileStorageManager.OpenFile(); // fileStorageManager.OpenFile();
// List all opened files // // List all opened files
Console.WriteLine("\nOpened Files:"); // Console.WriteLine("\nOpened Files:");
fileStorageManager.ListOpenedFiles(); // fileStorageManager.ListOpenedFiles();
// Example: Adding related objects to the first opened file (if any) // // Example: Adding related objects to the first opened file (if any)
var openedFiles = new List<Guid>(fileStorageManager._openedFiles.Keys); // var openedFiles = new List<Guid>(fileStorageManager._openedFiles.Keys);
if (openedFiles.Count > 0) // if (openedFiles.Count > 0)
{ // {
var firstFileId = openedFiles[0]; // var firstFileId = openedFiles[0];
var relatedObject = new FileRelatedObject("Sample Object", "This is a sample description"); // var relatedObject = new FileRelatedObject("Sample Object", "This is a sample description");
fileStorageManager.AddRelatedObjectToFile(firstFileId, relatedObject); // fileStorageManager.AddRelatedObjectToFile(firstFileId, relatedObject);
Console.WriteLine("\nAfter Adding Related Object:"); // Console.WriteLine("\nAfter Adding Related Object:");
fileStorageManager.ListOpenedFiles(); // fileStorageManager.ListOpenedFiles();
// Retrieve related object // // Retrieve related object
var retrievedObject = fileStorageManager.GetRelatedObjectFromFile(firstFileId, relatedObject.Id); // var retrievedObject = fileStorageManager.GetRelatedObjectFromFile(firstFileId, relatedObject.Id);
Console.WriteLine($"\nRetrieved Related Object: {retrievedObject}"); // Console.WriteLine($"\nRetrieved Related Object: {retrievedObject}");
// Remove related object // // Remove related object
fileStorageManager.RemoveRelatedObjectFromFile(firstFileId, relatedObject.Id); // fileStorageManager.RemoveRelatedObjectFromFile(firstFileId, relatedObject.Id);
Console.WriteLine("\nAfter Removing Related Object:"); // Console.WriteLine("\nAfter Removing Related Object:");
fileStorageManager.ListOpenedFiles(); // fileStorageManager.ListOpenedFiles();
} // }
// Close all files // // Close all files
foreach (var fileId in openedFiles) // foreach (var fileId in openedFiles)
{ // {
fileStorageManager.CloseFile(fileId); // fileStorageManager.CloseFile(fileId);
} // }
} // }
} //}
} }