FileWork examples were added
This commit is contained in:
21
DataAccess/DTOs/CrossSectionDTO.cs
Normal file
21
DataAccess/DTOs/CrossSectionDTO.cs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
using StructureHelperLogics.Models.CrossSections;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace DataAccess.DTOs
|
||||||
|
{
|
||||||
|
public class CrossSectionDTO : ICrossSection
|
||||||
|
{
|
||||||
|
public ICrossSectionRepository SectionRepository { get; }
|
||||||
|
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
|
||||||
|
public object Clone()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
18
DataAccess/DataAccess.csproj
Normal file
18
DataAccess/DataAccess.csproj
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net6.0-windows</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\StructureHelperCommon\StructureHelperCommon.csproj" />
|
||||||
|
<ProjectReference Include="..\StructureHelperLogics\StructureHelperLogics.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
124
DataAccess/Example.cs
Normal file
124
DataAccess/Example.cs
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
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
|
||||||
|
{
|
||||||
|
static void Main(string[] args)
|
||||||
|
{
|
||||||
|
var logger = new TraceLogger();
|
||||||
|
|
||||||
|
// Create objects with complex relationships
|
||||||
|
var parent1 = new Parent { Name = "Parent_1" };
|
||||||
|
var parent2 = new Parent { Name = "Parent_2" };
|
||||||
|
|
||||||
|
var detail1 = new Detail { Description = "Detail_1", InternalNote = "Secret Note 1" };
|
||||||
|
var detail2 = new Detail { Description = "Detail_2", InternalNote = "Secret Note 2" };
|
||||||
|
var detail3 = new Detail { Description = "Detail_3", InternalNote = "Secret Note 3" };
|
||||||
|
|
||||||
|
var subDetail1 = new SubDetail { Info = "SubDetail_1" };
|
||||||
|
|
||||||
|
// Set up relationships
|
||||||
|
parent1.Details.Add(detail1);
|
||||||
|
parent1.Details.Add(detail2);
|
||||||
|
|
||||||
|
parent2.Details.Add(detail2); // Shared detail
|
||||||
|
parent2.Details.Add(detail3);
|
||||||
|
|
||||||
|
detail3.SubDetails.Add(subDetail1);
|
||||||
|
|
||||||
|
// Serialize with custom converters and trace logging
|
||||||
|
string json = Serialize(new List<Parent> { parent1, parent2 }, logger);
|
||||||
|
Console.WriteLine("Serialized JSON:");
|
||||||
|
Console.WriteLine(json);
|
||||||
|
|
||||||
|
// Deserialize with custom converters and trace logging
|
||||||
|
var deserializedParents = Deserialize<List<Parent>>(json, logger);
|
||||||
|
|
||||||
|
Console.WriteLine("\nDeserialized Objects:");
|
||||||
|
foreach (var parent in deserializedParents)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Parent: {parent.Name}, Id: {parent.Id}");
|
||||||
|
foreach (var detail in parent.Details)
|
||||||
|
{
|
||||||
|
Console.WriteLine($" Detail: {detail.Description}, Id: {detail.Id}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static string Serialize(object obj, TraceLogger logger)
|
||||||
|
{
|
||||||
|
var settings = new JsonSerializerSettings
|
||||||
|
{
|
||||||
|
Converters = new List<JsonConverter>
|
||||||
|
{
|
||||||
|
new ParentConverter(logger), // Add the specific converter
|
||||||
|
// Add other converters if needed
|
||||||
|
},
|
||||||
|
Formatting = Formatting.Indented
|
||||||
|
};
|
||||||
|
|
||||||
|
return JsonConvert.SerializeObject(obj, settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
static T Deserialize<T>(string json, TraceLogger logger)
|
||||||
|
{
|
||||||
|
var settings = new JsonSerializerSettings
|
||||||
|
{
|
||||||
|
Converters = new List<JsonConverter>
|
||||||
|
{
|
||||||
|
new ParentConverter(logger), // Add the specific converter
|
||||||
|
// Add other converters if needed
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
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 string Name { get; set; }
|
||||||
|
|
||||||
|
public List<Detail> Details { get; set; } = new List<Detail>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Detail
|
||||||
|
{
|
||||||
|
public Guid Id { get; set; } = Guid.NewGuid();
|
||||||
|
|
||||||
|
[JsonPropertyName("detail_description")] // Compatible with System.Text.Json
|
||||||
|
public string Description { get; set; }
|
||||||
|
|
||||||
|
[JsonIgnore] // This property will be ignored during serialization
|
||||||
|
public string InternalNote { get; set; }
|
||||||
|
|
||||||
|
public List<SubDetail> SubDetails { get; set; } = new List<SubDetail>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SubDetail
|
||||||
|
{
|
||||||
|
public Guid Id { get; set; } = Guid.NewGuid();
|
||||||
|
public string Info { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
49
DataAccess/FileDialogs/FileDialogOpener.cs
Normal file
49
DataAccess/FileDialogs/FileDialogOpener.cs
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
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.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
93
DataAccess/FileDialogs/FileRepository.cs
Normal file
93
DataAccess/FileDialogs/FileRepository.cs
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace DataAccess.FileDialogs
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
public class FileRepository : IFileRepository
|
||||||
|
{
|
||||||
|
private readonly string _storageDirectory;
|
||||||
|
|
||||||
|
public FileRepository(string storageDirectory)
|
||||||
|
{
|
||||||
|
_storageDirectory = storageDirectory;
|
||||||
|
|
||||||
|
// Ensure the storage directory exists
|
||||||
|
if (!Directory.Exists(_storageDirectory))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(_storageDirectory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save a file to the repository
|
||||||
|
public async Task SaveFileAsync(Stream fileStream, string fileName)
|
||||||
|
{
|
||||||
|
string filePath = Path.Combine(_storageDirectory, fileName);
|
||||||
|
|
||||||
|
// Ensure the file does not already exist
|
||||||
|
if (File.Exists(filePath))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("File already exists.");
|
||||||
|
}
|
||||||
|
|
||||||
|
using (var file = new FileStream(filePath, FileMode.Create, FileAccess.Write))
|
||||||
|
{
|
||||||
|
await fileStream.CopyToAsync(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve a file from the repository
|
||||||
|
public async Task<Stream> GetFileAsync(string fileName)
|
||||||
|
{
|
||||||
|
string filePath = Path.Combine(_storageDirectory, fileName);
|
||||||
|
|
||||||
|
// Ensure the file exists
|
||||||
|
if (!File.Exists(filePath))
|
||||||
|
{
|
||||||
|
throw new FileNotFoundException("File not found.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
|
||||||
|
return await Task.FromResult(fileStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update an existing file in the repository
|
||||||
|
public async Task UpdateFileAsync(Stream fileStream, string fileName)
|
||||||
|
{
|
||||||
|
string filePath = Path.Combine(_storageDirectory, fileName);
|
||||||
|
|
||||||
|
// Ensure the file exists
|
||||||
|
if (!File.Exists(filePath))
|
||||||
|
{
|
||||||
|
throw new FileNotFoundException("File not found.");
|
||||||
|
}
|
||||||
|
|
||||||
|
using (var file = new FileStream(filePath, FileMode.Truncate, FileAccess.Write))
|
||||||
|
{
|
||||||
|
await fileStream.CopyToAsync(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete a file from the repository
|
||||||
|
public async Task DeleteFileAsync(string fileName)
|
||||||
|
{
|
||||||
|
string filePath = Path.Combine(_storageDirectory, fileName);
|
||||||
|
|
||||||
|
// Ensure the file exists
|
||||||
|
if (!File.Exists(filePath))
|
||||||
|
{
|
||||||
|
throw new FileNotFoundException("File not found.");
|
||||||
|
}
|
||||||
|
|
||||||
|
File.Delete(filePath);
|
||||||
|
await Task.CompletedTask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
139
DataAccess/FileDialogs/FileStorage.cs
Normal file
139
DataAccess/FileDialogs/FileStorage.cs
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
using DataAccess.FileDialogs;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace DataAccess.FileDialogs
|
||||||
|
{
|
||||||
|
internal class FileStorage
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
public class FileStorageManager
|
||||||
|
{
|
||||||
|
// Dictionary to store files with unique IDs as keys
|
||||||
|
private readonly Dictionary<Guid, OpenedFile> _openedFiles = new Dictionary<Guid, OpenedFile>();
|
||||||
|
|
||||||
|
// Method to open a file and add it to the storage
|
||||||
|
public Guid OpenFile()
|
||||||
|
{
|
||||||
|
using (OpenFileDialog openFileDialog = new OpenFileDialog())
|
||||||
|
{
|
||||||
|
openFileDialog.Filter = "Text Files (*.txt)|*.txt|All Files (*.*)|*.*";
|
||||||
|
openFileDialog.Multiselect = true; // Allow multiple file selection
|
||||||
|
openFileDialog.Title = "Select Files";
|
||||||
|
|
||||||
|
if (openFileDialog.ShowDialog() == DialogResult.OK)
|
||||||
|
{
|
||||||
|
foreach (var filePath in openFileDialog.FileNames)
|
||||||
|
{
|
||||||
|
var fileId = Guid.NewGuid();
|
||||||
|
var openedFile = new OpenedFile(fileId, filePath);
|
||||||
|
|
||||||
|
// Add to storage
|
||||||
|
_openedFiles[fileId] = openedFile;
|
||||||
|
|
||||||
|
Console.WriteLine($"File '{openedFile.FilePath}' opened with ID: {fileId}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Guid.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method to get an opened file by ID
|
||||||
|
public OpenedFile GetFile(Guid fileId)
|
||||||
|
{
|
||||||
|
if (_openedFiles.TryGetValue(fileId, out var openedFile))
|
||||||
|
{
|
||||||
|
return openedFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new KeyNotFoundException("File not found.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method to close a file by ID
|
||||||
|
public void CloseFile(Guid fileId)
|
||||||
|
{
|
||||||
|
if (_openedFiles.ContainsKey(fileId))
|
||||||
|
{
|
||||||
|
_openedFiles.Remove(fileId);
|
||||||
|
Console.WriteLine($"File with ID: {fileId} has been closed.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new KeyNotFoundException("File not found.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method to read content of an opened file by ID
|
||||||
|
public string ReadFileContent(Guid fileId)
|
||||||
|
{
|
||||||
|
var openedFile = GetFile(fileId);
|
||||||
|
return File.ReadAllText(openedFile.FilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method to list all opened files
|
||||||
|
public void ListOpenedFiles()
|
||||||
|
{
|
||||||
|
foreach (var file in _openedFiles.Values)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"File ID: {file.Id}, Path: {file.FilePath}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Class representing an opened file
|
||||||
|
public class OpenedFile
|
||||||
|
{
|
||||||
|
public Guid Id { get; }
|
||||||
|
public string FilePath { get; }
|
||||||
|
|
||||||
|
public OpenedFile(Guid id, string filePath)
|
||||||
|
{
|
||||||
|
Id = id;
|
||||||
|
FilePath = filePath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class Program
|
||||||
|
{
|
||||||
|
[STAThread] // Required for OpenFileDialog
|
||||||
|
static void Main()
|
||||||
|
{
|
||||||
|
var fileStorageManager = new FileStorageManager();
|
||||||
|
|
||||||
|
// Open files and add them to the storage
|
||||||
|
fileStorageManager.OpenFile();
|
||||||
|
|
||||||
|
// List all opened files
|
||||||
|
Console.WriteLine("\nOpened Files:");
|
||||||
|
fileStorageManager.ListOpenedFiles();
|
||||||
|
|
||||||
|
// Example: Read content of the first opened file (if any)
|
||||||
|
var openedFiles = new List<Guid>(fileStorageManager._openedFiles.Keys);
|
||||||
|
if (openedFiles.Count > 0)
|
||||||
|
{
|
||||||
|
var firstFileId = openedFiles[0];
|
||||||
|
Console.WriteLine($"\nReading content of the first opened file (ID: {firstFileId}):");
|
||||||
|
string content = fileStorageManager.ReadFileContent(firstFileId);
|
||||||
|
Console.WriteLine(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close all files
|
||||||
|
foreach (var fileId in openedFiles)
|
||||||
|
{
|
||||||
|
fileStorageManager.CloseFile(fileId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
14
DataAccess/FileDialogs/IFileRepository.cs
Normal file
14
DataAccess/FileDialogs/IFileRepository.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
using System.IO;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace DataAccess.FileDialogs
|
||||||
|
{
|
||||||
|
public interface IFileRepository
|
||||||
|
{
|
||||||
|
Task SaveFileAsync(Stream fileStream, string fileName);
|
||||||
|
Task<Stream> GetFileAsync(string fileName);
|
||||||
|
Task DeleteFileAsync(string fileName);
|
||||||
|
Task UpdateFileAsync(Stream fileStream, string fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
62
DataAccess/FileDialogs/ProgramExample.cs
Normal file
62
DataAccess/FileDialogs/ProgramExample.cs
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace DataAccess.FileDialogs
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
class ProgramExample
|
||||||
|
{
|
||||||
|
static async Task Main(string[] args)
|
||||||
|
{
|
||||||
|
string storagePath = Path.Combine(Environment.CurrentDirectory, "UserFiles");
|
||||||
|
IFileRepository fileRepository = new FileRepository(storagePath);
|
||||||
|
|
||||||
|
// Save a file
|
||||||
|
string fileName = "example.txt";
|
||||||
|
using (var fileStream = new MemoryStream(Encoding.UTF8.GetBytes("Hello, World!")))
|
||||||
|
{
|
||||||
|
await fileRepository.SaveFileAsync(fileStream, fileName);
|
||||||
|
Console.WriteLine($"File '{fileName}' saved.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve a file
|
||||||
|
using (Stream retrievedFile = await fileRepository.GetFileAsync(fileName))
|
||||||
|
{
|
||||||
|
using (var reader = new StreamReader(retrievedFile))
|
||||||
|
{
|
||||||
|
string content = await reader.ReadToEndAsync();
|
||||||
|
Console.WriteLine($"Retrieved file content: {content}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update a file
|
||||||
|
using (var updateStream = new MemoryStream(Encoding.UTF8.GetBytes("Updated content!")))
|
||||||
|
{
|
||||||
|
await fileRepository.UpdateFileAsync(updateStream, fileName);
|
||||||
|
Console.WriteLine($"File '{fileName}' updated.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve updated file
|
||||||
|
using (Stream updatedFile = await fileRepository.GetFileAsync(fileName))
|
||||||
|
{
|
||||||
|
using (var reader = new StreamReader(updatedFile))
|
||||||
|
{
|
||||||
|
string updatedContent = await reader.ReadToEndAsync();
|
||||||
|
Console.WriteLine($"Updated file content: {updatedContent}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete a file
|
||||||
|
await fileRepository.DeleteFileAsync(fileName);
|
||||||
|
Console.WriteLine($"File '{fileName}' deleted.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
95
DataAccess/JsonConverters/BaseConverter.cs
Normal file
95
DataAccess/JsonConverters/BaseConverter.cs
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
17
DataAccess/JsonConverters/CrossSectionJsonConverter.cs
Normal file
17
DataAccess/JsonConverters/CrossSectionJsonConverter.cs
Normal 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 CrossSectionJsonConverter : BaseConverter<CrossSectionDTO>
|
||||||
|
{
|
||||||
|
public CrossSectionJsonConverter(IShiftTraceLogger logger) : base(logger)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,6 +18,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FieldVisualizer", "FieldVis
|
|||||||
{F1548BD2-7FE8-46C2-9BC4-9BA813A5C59A} = {F1548BD2-7FE8-46C2-9BC4-9BA813A5C59A}
|
{F1548BD2-7FE8-46C2-9BC4-9BA813A5C59A} = {F1548BD2-7FE8-46C2-9BC4-9BA813A5C59A}
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataAccess", "DataAccess\DataAccess.csproj", "{BB820532-B66E-4876-903D-D6208C2A5352}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@@ -48,6 +50,10 @@ Global
|
|||||||
{6CAC5B83-81F3-47C2-92A1-0F94A58491C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{6CAC5B83-81F3-47C2-92A1-0F94A58491C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{6CAC5B83-81F3-47C2-92A1-0F94A58491C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{6CAC5B83-81F3-47C2-92A1-0F94A58491C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{6CAC5B83-81F3-47C2-92A1-0F94A58491C2}.Release|Any CPU.Build.0 = Release|Any CPU
|
{6CAC5B83-81F3-47C2-92A1-0F94A58491C2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{BB820532-B66E-4876-903D-D6208C2A5352}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{BB820532-B66E-4876-903D-D6208C2A5352}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{BB820532-B66E-4876-903D-D6208C2A5352}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{BB820532-B66E-4876-903D-D6208C2A5352}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
89
StructureHelperLogics/Models/Storages/FileStorageManager.cs
Normal file
89
StructureHelperLogics/Models/Storages/FileStorageManager.cs
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace StructureHelperLogics.Models.Storages
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
public class FileStorageManager
|
||||||
|
{
|
||||||
|
private readonly Dictionary<Guid, OpenedFile> _openedFiles = new Dictionary<Guid, OpenedFile>();
|
||||||
|
|
||||||
|
public void OpenFile()
|
||||||
|
{
|
||||||
|
using (OpenFileDialog openFileDialog = new OpenFileDialog())
|
||||||
|
{
|
||||||
|
openFileDialog.Filter = "Text Files (*.txt)|*.txt|All Files (*.*)|*.*";
|
||||||
|
openFileDialog.Multiselect = true;
|
||||||
|
openFileDialog.Title = "Select Files";
|
||||||
|
|
||||||
|
if (openFileDialog.ShowDialog() == DialogResult.OK)
|
||||||
|
{
|
||||||
|
foreach (var filePath in openFileDialog.FileNames)
|
||||||
|
{
|
||||||
|
var fileId = Guid.NewGuid();
|
||||||
|
var openedFile = new OpenedFile(fileId, filePath);
|
||||||
|
|
||||||
|
_openedFiles[fileId] = openedFile;
|
||||||
|
|
||||||
|
Console.WriteLine($"File '{openedFile.FilePath}' opened with ID: {fileId}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public OpenedFile GetFile(Guid fileId)
|
||||||
|
{
|
||||||
|
if (_openedFiles.TryGetValue(fileId, out var openedFile))
|
||||||
|
{
|
||||||
|
return openedFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new KeyNotFoundException("File not found.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CloseFile(Guid fileId)
|
||||||
|
{
|
||||||
|
if (_openedFiles.ContainsKey(fileId))
|
||||||
|
{
|
||||||
|
_openedFiles.Remove(fileId);
|
||||||
|
Console.WriteLine($"File with ID: {fileId} has been closed.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new KeyNotFoundException("File not found.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddRelatedObjectToFile(Guid fileId, FileRelatedObject relatedObject)
|
||||||
|
{
|
||||||
|
var openedFile = GetFile(fileId);
|
||||||
|
openedFile.AddRelatedObject(relatedObject);
|
||||||
|
Console.WriteLine($"Added related object to file ID: {fileId}, Related Object: {relatedObject}");
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileRelatedObject GetRelatedObjectFromFile(Guid fileId, Guid objectId)
|
||||||
|
{
|
||||||
|
var openedFile = GetFile(fileId);
|
||||||
|
return openedFile.GetRelatedObject(objectId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveRelatedObjectFromFile(Guid fileId, Guid objectId)
|
||||||
|
{
|
||||||
|
var openedFile = GetFile(fileId);
|
||||||
|
openedFile.RemoveRelatedObject(objectId);
|
||||||
|
Console.WriteLine($"Removed related object with ID: {objectId} from file ID: {fileId}");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ListOpenedFiles()
|
||||||
|
{
|
||||||
|
foreach (var file in _openedFiles.Values)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"File ID: {file.Id}, Path: {file.FilePath}, Related Objects Count: {file.RelatedObjects.Count}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
84
StructureHelperLogics/Models/Storages/OpenedFile.cs
Normal file
84
StructureHelperLogics/Models/Storages/OpenedFile.cs
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
using StructureHelperCommon.Infrastructures.Interfaces;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace StructureHelperLogics.Models.Storages
|
||||||
|
{
|
||||||
|
public class OpenedFile
|
||||||
|
{
|
||||||
|
public Guid Id { get; }
|
||||||
|
public string FilePath { get; }
|
||||||
|
public List<ISaveable> RelatedObjects { get; } // List of related objects
|
||||||
|
|
||||||
|
public OpenedFile(Guid id, string filePath)
|
||||||
|
{
|
||||||
|
Id = id;
|
||||||
|
FilePath = filePath;
|
||||||
|
RelatedObjects = new List<ISaveable>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddRelatedObject(ISaveable relatedObject)
|
||||||
|
{
|
||||||
|
RelatedObjects.Add(relatedObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveRelatedObject(Guid objectId)
|
||||||
|
{
|
||||||
|
RelatedObjects.RemoveAll(o => o.Id == objectId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ISaveable GetRelatedObject(Guid objectId)
|
||||||
|
{
|
||||||
|
return RelatedObjects.Find(o => o.Id == objectId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Program
|
||||||
|
{
|
||||||
|
[STAThread] // Required for OpenFileDialog
|
||||||
|
static void Main()
|
||||||
|
{
|
||||||
|
var fileStorageManager = new FileStorageManager();
|
||||||
|
|
||||||
|
// Open files and add them to the storage
|
||||||
|
fileStorageManager.OpenFile();
|
||||||
|
|
||||||
|
// List all opened files
|
||||||
|
Console.WriteLine("\nOpened Files:");
|
||||||
|
fileStorageManager.ListOpenedFiles();
|
||||||
|
|
||||||
|
// Example: Adding related objects to the first opened file (if any)
|
||||||
|
var openedFiles = new List<Guid>(fileStorageManager._openedFiles.Keys);
|
||||||
|
if (openedFiles.Count > 0)
|
||||||
|
{
|
||||||
|
var firstFileId = openedFiles[0];
|
||||||
|
var relatedObject = new FileRelatedObject("Sample Object", "This is a sample description");
|
||||||
|
fileStorageManager.AddRelatedObjectToFile(firstFileId, relatedObject);
|
||||||
|
|
||||||
|
Console.WriteLine("\nAfter Adding Related Object:");
|
||||||
|
fileStorageManager.ListOpenedFiles();
|
||||||
|
|
||||||
|
// Retrieve related object
|
||||||
|
var retrievedObject = fileStorageManager.GetRelatedObjectFromFile(firstFileId, relatedObject.Id);
|
||||||
|
Console.WriteLine($"\nRetrieved Related Object: {retrievedObject}");
|
||||||
|
|
||||||
|
// Remove related object
|
||||||
|
fileStorageManager.RemoveRelatedObjectFromFile(firstFileId, relatedObject.Id);
|
||||||
|
|
||||||
|
Console.WriteLine("\nAfter Removing Related Object:");
|
||||||
|
fileStorageManager.ListOpenedFiles();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close all files
|
||||||
|
foreach (var fileId in openedFiles)
|
||||||
|
{
|
||||||
|
fileStorageManager.CloseFile(fileId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user