Continuo implementazione servizi serializzazione json/XML esterni + fix trasformazioni

This commit is contained in:
Samuele Locatelli
2026-05-20 14:49:33 +02:00
parent 1c543d2219
commit ed019cafa7
5 changed files with 214 additions and 65 deletions
+2
View File
@@ -133,6 +133,8 @@
<Compile Include="Iob\BaseObj.cs" />
<Compile Include="Iob\Generic.cs" />
<Compile Include="Iob\PingWatchDog.cs" />
<Compile Include="Iob\Services\DataSerializer.cs" />
<Compile Include="Iob\Services\XmlDataSerializer.cs" />
<Compile Include="Iob\Simula.cs" />
<Compile Include="MainForm.cs">
<SubType>Form</SubType>
+68 -65
View File
@@ -25,7 +25,7 @@ using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Serialization;
using IOB_WIN_FORM.Iob.Services;
using YamlDotNet.Core.Tokens;
using static IOB_UT_NEXT.BaseAlarmConf;
using static IOB_UT_NEXT.CustomObj;
@@ -410,7 +410,7 @@ namespace IOB_WIN_FORM.Iob
/// <returns></returns>
public static Dictionary<string, string> ConvertToStringDict(Dictionary<string, object> input)
{
return input.ToDictionary(pair => pair.Key, pair => pair.Value?.ToString());
return DataSerializer.ToDictionary(input);
}
/// <summary>
@@ -544,7 +544,7 @@ namespace IOB_WIN_FORM.Iob
}
BaseRawTransf newVal = new BaseRawTransf(DateTime.Now, njObj, mesType);
string encodedVal = JsonConvert.SerializeObject(newVal);
string encodedVal = DataSerializer.Serialize(newVal);
// --> accodo (valore già formattato)!
QueueRawTransf.Enqueue(encodedVal);
// se abilitato controllo coda Max (superiore a 0...)
@@ -1976,11 +1976,11 @@ namespace IOB_WIN_FORM.Iob
string rawVal = redisMan.redGetHashField(lastSendKey, keyReq);
if (!string.IsNullOrEmpty(rawVal))
{
lastSend = JsonConvert.DeserializeObject<DateTime>(rawVal);
lastSend = DataSerializer.Deserialize<DateTime>(rawVal);
}
else
{
rawVal = JsonConvert.SerializeObject(lastSend);
rawVal = DataSerializer.Serialize(lastSend);
KeyValuePair<string, string>[] hashFields = new KeyValuePair<string, string>[1];
hashFields[0] = new KeyValuePair<string, string>(keyReq, rawVal);
redisMan.redSaveHash(lastSendKey, hashFields);
@@ -1996,13 +1996,14 @@ namespace IOB_WIN_FORM.Iob
public bool LastSendSet(string keyReq, DateTime dtRif)
{
string lastSendKey = redisMan.redHash($"IOB:Status:{IOBConfFull.General.FilenameIOB}:LastSend");
string rawVal = JsonConvert.SerializeObject(dtRif);
string rawVal = DataSerializer.Serialize(dtRif);
KeyValuePair<string, string>[] hashFields = new KeyValuePair<string, string>[1];
hashFields[0] = new KeyValuePair<string, string>(keyReq, rawVal);
bool fatto = redisMan.redSaveHash(lastSendKey, hashFields);
return fatto;
}
/// <summary>
/// Effettua un trim della stringa al numero max di linee da mostrare a video
/// </summary>
@@ -6806,38 +6807,28 @@ namespace IOB_WIN_FORM.Iob
// leggo contenuto XML
string rawData = File.ReadAllText(recipeFile);
// deserializza file XML x recuperare righe consumo
XmlSerializer serializer = new XmlSerializer(typeof(ARecipe));
using (StringReader reader = new StringReader(rawData))
var currRecipe = XmlDataSerializer.Deserialize<ARecipe>(rawData);
if (currRecipe != null)
{
try
// recupero data-ora ricetta da campo string
DateTime recExeDt = DateTime.Today;
DateTime.TryParse(currRecipe.DesRecipe.DesData.Date, out recExeDt);
// calcolo week da data-ora file...
week = cal.GetWeekOfYear(recExeDt, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
// verifico se ci sia la settimana indicata in elenco...
string currWeek = $"{recExeDt:yyyy}-{week:00}";
if (!weeksProc.Contains(currWeek))
{
var currRecipe = (ARecipe)serializer.Deserialize(reader);
if (currRecipe != null)
{
// recupero data-ora ricetta da campo string
DateTime recExeDt = DateTime.Today;
DateTime.TryParse(currRecipe.DesRecipe.DesData.Date, out recExeDt);
// calcolo week da data-ora file...
week = cal.GetWeekOfYear(recExeDt, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
// verifico se ci sia la settimana indicata in elenco...
string currWeek = $"{recExeDt:yyyy}-{week:00}";
if (!weeksProc.Contains(currWeek))
{
weeksProc.Add(currWeek);
}
// sposto file x in area week
string rName = Path.GetFileName(recipeFile);
archPath = Path.Combine(archBasePath, $"{recExeDt:yyyy}-{week:00}");
baseUtils.checkDir(archPath);
string destPath = Path.Combine(archPath, rName);
// sposto files
File.Move(recipeFile, destPath);
}
}
catch (Exception exc)
{
lgError($"Eccezione in RecipeDoArchiveWeek{Environment.NewLine}{exc}");
weeksProc.Add(currWeek);
}
// sposto file x in area week
string rName = Path.GetFileName(recipeFile);
archPath = Path.Combine(archBasePath, $"{recExeDt:yyyy}-{week:00}");
baseUtils.checkDir(archPath);
string destPath = Path.Combine(archPath, rName);
// sposto files
File.Move(recipeFile, destPath);
}
return weeksProc;
}
@@ -7041,45 +7032,57 @@ namespace IOB_WIN_FORM.Iob
// leggo contenuto XML
string rawData = File.ReadAllText(recipeFile);
// deserializza file XML x recuperare righe consumo
XmlSerializer serializer = new XmlSerializer(typeof(ARecipe));
using (StringReader reader = new StringReader(rawData))
var currRecipe = XmlDataSerializer.Deserialize<ARecipe>(rawData);
if (currRecipe != null)
{
try
if (currRecipe.ColRecipe != null && currRecipe.ColRecipe.Count > 0)
{
var currRecipe = (ARecipe)serializer.Deserialize(reader);
if (currRecipe != null)
List<ColData> RigheConsumi = new List<ColData>();
foreach (var rigaComp in currRecipe.ColRecipe)
{
if (currRecipe.ColRecipe != null && currRecipe.ColRecipe.Count > 0)
{
List<ColData> RigheConsumi = new List<ColData>();
foreach (var rigaComp in currRecipe.ColRecipe)
{
ColData datiComp = rigaComp.ColData;
RigheConsumi.Add(datiComp);
}
// recupero data-ora ricetta da campo string
DateTime recExeDt = DateTime.Today;
DateTime.TryParse(currRecipe.DesRecipe.DesData.Date, out recExeDt);
// converto le righe di consumo ColData in ConsRec
listConsumi = RigheConsumi.Select(x => new ConsRec()
{
FileRef = recipeFile,
DtRif = recExeDt,
ColourCode = x.ColourCode,
Description = x.Description,
WeightGrTot = x.Weightgrtotal
}).ToList();
}
ColData datiComp = rigaComp.ColData;
RigheConsumi.Add(datiComp);
}
}
catch (Exception exc)
{
lgError($"Eccezione in RecipeGetCons{Environment.NewLine}{exc}");
// recupero data-ora ricetta da campo string
DateTime recExeDt = DateTime.Today;
DateTime.TryParse(currRecipe.DesRecipe.DesData.Date, out recExeDt);
// converto le righe di consumo ColData in ConsRec
listConsumi = RigheConsumi.Select(x => new ConsRec()
{
FileRef = recipeFile,
DtRif = recExeDt,
ColourCode = x.ColourCode,
Description = x.Description,
WeightGrTot = x.Weightgrtotal
}).ToList();
}
}
return listConsumi;
}
// // recupero data-ora ricetta da campo string
// DateTime recExeDt = DateTime.Today;
// DateTime.TryParse(currRecipe.DesRecipe.DesData.Date, out recExeDt);
// // converto le righe di consumo ColData in ConsRec
// listConsumi = RigheConsumi.Select(x => new ConsRec()
// {
// FileRef = recipeFile,
// DtRif = recExeDt,
// ColourCode = x.ColourCode,
// Description = x.Description,
// WeightGrTot = x.Weightgrtotal
// }).ToList();
// }
// }
// }
// catch (Exception exc)
// {
// lgError($"Eccezione in RecipeGetCons{Environment.NewLine}{exc}");
// }
// }
// return listConsumi;
// }
/// <summary>
/// Prepara la ricetta indicata partendo dai dati della ricetta template + dati ODL di riferimento
/// </summary>
@@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using Newtonsoft.Json;
namespace IOB_WIN_FORM.Iob.Services
{
/// <summary>
/// Gestisce tutte le operazioni di serializzazione e deserializzazione dei dati.
/// </summary>
public static class DataSerializer
{
/// <summary>
/// Serializza un oggetto in una stringa JSON utilizzando la cultura invariante.
/// </summary>
public static string Serialize<T>(T obj)
{
if (obj == null) return null;
// Utilizzo di CultureInfo.InvariantCulture per garantire la coerenza dei formati (es. decimali)
return JsonConvert.SerializeObject(obj, new JsonSerializerSettings
{
Culture = CultureInfo.InvariantCulture
});
}
/// <summary>
/// Deserializza una stringa JSON in un oggetto del tipo specificato.
/// </summary>
public static T Deserialize<T>(string json)
{
if (string.IsNullOrWhiteSpace(json)) return default;
return JsonConvert.DeserializeObject<T>(json, new JsonSerializerSettings
{
Culture = CultureInfo.InvariantCulture
});
}
/// <summary>
/// Helper per convertire un dizionario di oggetti in un dizionario di stringhe.
/// </summary>
public static Dictionary<string, string> ToDictionary(Dictionary<string, object> input)
{
if (input == null) return new Dictionary<string, string>();
var dict = new Dictionary<string, string>();
foreach (var pair in input)
{
dict[pair.Key] = pair.Value?.ToString();
}
return dict;
}
}
}
@@ -0,0 +1,63 @@
using System;
using System.IO;
using System.Xml.Serialization;
namespace IOB_WIN_FORM.Iob.Services
{
/// <summary>
/// Gestisce le operazioni di serializzazione e deserializzazione in formato XML.
/// </summary>
public static class XmlDataSerializer
{
/// <summary>
/// Serializza un oggetto in una stringa XML.
/// </summary>
/// <typeparam name="T">Tipo dell'oggetto.</typeparam>
/// <param name="obj">L'oggetto da serializzare.</param>
/// <returns>Stringa XML o null se l'oggetto è null.</returns>
public static string Serialize<T>(T obj)
{
if (obj == null) return null;
try
{
using (var stringWriter = new StringWriter())
{
var serializer = new XmlSerializer(typeof(T));
serializer.Serialize(stringWriter, obj);
return stringWriter.ToString();
}
}
catch (Exception ex)
{
// Log l'errore se necessario. In un contesto di refactoring,
// potremmo voler passare l'eccezione verso l'alto.
throw new InvalidOperationException($"Errore durante la serializzazione XML per il tipo {typeof(T).Name}", ex);
}
}
/// <summary>
/// Deserializza una stringa XML in un oggetto del tipo specificato.
/// </summary>
/// <typeparam name="T">Tipo dell'oggetto.</typeparam>
/// <param name="xmlString">La stringa XML.</param>
/// <returns>L'oggetto deserializzato o default se la stringa è nulla/vuota.</returns>
public static T Deserialize<T>(string xmlString)
{
if (string.IsNullOrWhiteSpace(xmlString)) return default;
try
{
using (var stringReader = new StringReader(xmlString))
{
var serializer = new XmlSerializer(typeof(T));
return (T)serializer.Deserialize(stringReader);
}
}
catch (Exception ex)
{
throw new InvalidOperationException($"Errore durante la deserializzazione XML per il tipo {typeof(T).Name}", ex);
}
}
}
}
+28
View File
@@ -0,0 +1,28 @@
# WIP: Refactoring Phase 1 - Infrastructure Extraction
## Status: IN_PROGRESS
## Objective
Extract infrastructure and helper components from `Generic.cs` to improve modularity and reduce the monolithic footprint.
## Tasks
### 1. Communication Service Extraction
- [ ] Extract REST/HTTP logic (currently using `utils.callUrl`, `callUrlWithPayloadAsync`, etc.).
- [ ] Implement a singleton/service-based `CommunicationService` using `HttpClient`.
- [ ] **Italian Commenting Requirement**: All new/modified code comments must be in Italian.
### 2. Redis Service Extraction
- [ ] Encapsulate all `redisMan` calls into a `RedisService`.
- [ ] Define a clean interface for key/value and hash operations.
### 3. Data Serializer Extraction
- [ ] Move all `JsonConvert` and custom string formatting (e.g., `qEncodeFLog`, `qEncodeIN`) to a `DataSerializer` service.
- [ ] Centralize `CultureInfo.InvariantCulture` usage.
## Progress Log
- [x] Created WIP document.
- [x] Analyzed `Generic.cs` for Phase 1 candidates (found ~200 occurrences of key patterns).
- [ ] Started Extraction of `CommunicationService`.
- [ ] Started Extraction of `RedisService`.
- [ ] Started Extraction of `DataSerializer`.