Completamento migrazione repository MpSpecController: aggiunti MpMon, MpVoc, MpLand; migrati TranslateSrv, StatusData, LandDataService, TranslateSrv, MonDataFeeder, TabDataFeeder; 0 errori build

This commit is contained in:
Samuele E. Locatelli (W11-AI)
2026-06-02 23:59:01 +02:00
parent 843435ad3b
commit 328f7adc06
14 changed files with 496 additions and 92 deletions
+9 -1
View File
@@ -6,6 +6,9 @@ using MP.Data.Repository.Anag;
using MP.Data.Repository.Dossier;
using MP.Data.Repository.FluxLog;
using MP.Data.Repository.IOC;
using MP.Data.Repository.MpLand;
using MP.Data.Repository.MpMon;
using MP.Data.Repository.MpVoc;
using MP.Data.Repository.Mtc;
using MP.Data.Repository.Production;
using MP.Data.Repository.System;
@@ -61,6 +64,9 @@ namespace MP.Data
services.TryAddScoped<IDossierRepository, DossierRepository>();
services.TryAddScoped<IFluxLogRepository, FluxLogRepository>();
services.TryAddScoped<ISystemRepository, SystemRepository>();
services.TryAddScoped<IMpMonRepository, MpMonRepository>();
services.TryAddScoped<IMpVocRepository, MpVocRepository>();
services.TryAddScoped<IMpLandRepository, MpLandRepository>();
// ---------- End Repository ----------
@@ -70,6 +76,8 @@ namespace MP.Data
// Singleton
//services.TryAddSingleton<MpDataService>();
// Scoped
// ---------- End Servizi ----------
@@ -79,7 +87,7 @@ namespace MP.Data
// Singleton
services.TryAddSingleton<AppAuthService>();
services.TryAddScoped<OrderDataSrv>();
services.TryAddSingleton<ListSelectDataSrv>();
services.TryAddScoped<ListSelectDataSrv>();
services.TryAddSingleton<SharedMemService>();
services.TryAddSingleton<TabDataService>();
services.TryAddSingleton<TabDataFeeder>();
@@ -0,0 +1,23 @@
using Microsoft.Extensions.Configuration;
using MP.Data.DbModels;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace MP.Data.Repository.MpLand
{
public interface IMpLandRepository
{
Task<List<DbSizeModel>> AllDbInfoAsync();
Task<List<ConfigModel>> ConfigGetAllAsync();
Task<List<RemoteRebootLogModel>> RemRebootLogGetAllAsync();
Task<List<RemoteRebootLogModel>> RemRebootLogGetLastAsync();
Task<List<RemoteRebootLogModel>> RemRebootLogGetLastNoMaccAsync();
Task<List<MacchineModel>> MacchineGetAllAsync();
}
}
@@ -0,0 +1,162 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using MP.Data.DbModels;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace MP.Data.Repository.MpLand
{
public class MpLandRepository : IMpLandRepository
{
#region Private Fields
private readonly IConfiguration _configuration;
private readonly IDbContextFactory<MoonProContext> _ctxFactory;
#endregion
#region Public Constructors
public MpLandRepository(IConfiguration configuration, IDbContextFactory<MoonProContext> ctxFactory)
{
_configuration = configuration;
_ctxFactory = ctxFactory;
}
#endregion
#region Public Methods
/// <inheritdoc />
public async Task<List<DbSizeModel>> AllDbInfoAsync()
{
List<DbSizeModel> dbResult = new List<DbSizeModel>();
string stp_DbInfo = @"
;WITH TableRowCounts AS (
SELECT
t.name AS TableName,
SUM(p.rows) AS RowNum
FROM sys.tables t
JOIN sys.partitions p ON t.object_id = p.object_id
WHERE p.index_id IN (0, 1)
GROUP BY t.name
),
LargestTable AS (
SELECT TOP 1 RowNum, TableName
FROM TableRowCounts
ORDER BY RowNum DESC
)
SELECT
DB_name() as DbName,
CAST(SUM(size) * 8.0 / 1024 AS DECIMAL(18,2)) AS DbSizeMb,
(SELECT COUNT(*) FROM sys.tables) AS NumTables,
(SELECT TableName FROM LargestTable) AS BigTable,
(SELECT RowNum FROM LargestTable) AS BigTableRows
FROM sys.master_files
WHERE database_id = DB_ID();
";
try
{
if (!string.IsNullOrEmpty(_configuration.GetConnectionString("MP.All")))
{
await using var dbCtx = await _ctxFactory.CreateDbContextAsync();
var singleRes = await dbCtx
.DbSetDbSize
.FromSqlRaw(stp_DbInfo)
.AsNoTracking()
.FirstOrDefaultAsync();
if (singleRes != null)
{
dbResult.Add(singleRes);
}
}
if (!string.IsNullOrEmpty(_configuration.GetConnectionString("MP.Flux")))
{
await using var dbCtx = new MoonPro_FluxContext(_configuration);
var singleRes = await dbCtx
.DbSetDbSize
.FromSqlRaw(stp_DbInfo)
.AsNoTracking()
.FirstOrDefaultAsync();
if (singleRes != null)
{
dbResult.Add(singleRes);
}
}
if (!string.IsNullOrEmpty(_configuration.GetConnectionString("MP.Stats")))
{
await using var dbCtx = new MoonPro_STATSContext(_configuration);
var singleRes = await dbCtx
.DbSetDbSize
.FromSqlRaw(stp_DbInfo)
.AsNoTracking()
.FirstOrDefaultAsync();
if (singleRes != null)
{
dbResult.Add(singleRes);
}
}
}
catch
{
}
return dbResult;
}
/// <inheritdoc />
public async Task<List<ConfigModel>> ConfigGetAllAsync()
{
await using var dbCtx = await _ctxFactory.CreateDbContextAsync();
return await dbCtx
.DbSetConfig
.AsNoTracking()
.OrderBy(x => x.Chiave)
.ToListAsync() ?? new();
}
/// <inheritdoc />
public async Task<List<MacchineModel>> MacchineGetAllAsync()
{
await using var dbCtx = await _ctxFactory.CreateDbContextAsync();
return await dbCtx
.DbSetMacchine
.ToListAsync() ?? new();
}
/// <inheritdoc />
public async Task<List<RemoteRebootLogModel>> RemRebootLogGetAllAsync()
{
await using var dbCtx = await _ctxFactory.CreateDbContextAsync();
return await dbCtx
.DbSetRemRebLog
.AsNoTracking()
.OrderByDescending(x => x.IdxReboot)
.ToListAsync() ?? new();
}
/// <inheritdoc />
public async Task<List<RemoteRebootLogModel>> RemRebootLogGetLastAsync()
{
await using var dbCtx = await _ctxFactory.CreateDbContextAsync();
return await dbCtx
.DbSetRemRebLog
.FromSqlRaw("EXEC stp_RRL_getLast")
.AsNoTracking()
.ToListAsync() ?? new();
}
/// <inheritdoc />
public async Task<List<RemoteRebootLogModel>> RemRebootLogGetLastNoMaccAsync()
{
await using var dbCtx = await _ctxFactory.CreateDbContextAsync();
return await dbCtx
.DbSetRemRebLog
.FromSqlRaw("EXEC stp_RRL_GetLastNoMachine")
.AsNoTracking()
.ToListAsync() ?? new();
}
#endregion
}
}
@@ -0,0 +1,20 @@
using Microsoft.Data.SqlClient;
using MP.Data.DbModels;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
namespace MP.Data.Repository.MpMon
{
public interface IMpMonRepository
{
Task<List<ConfigModel>> ConfigGetAllAsync();
Task<List<MacchineModel>> MacchineGetAllAsync();
Task<List<MacchineModel>> MacchineGetFiltAsync(string codGruppo);
Task<List<MappaStatoExplModel>> MseGetAllAsync(int maxAge = 2000);
}
}
+100
View File
@@ -0,0 +1,100 @@
using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore;
using MP.Data.DbModels;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
namespace MP.Data.Repository.MpMon
{
public class MpMonRepository : IMpMonRepository
{
#region Private Fields
private readonly IDbContextFactory<MoonProContext> _ctxFactory;
#endregion
#region Public Constructors
public MpMonRepository(IDbContextFactory<MoonProContext> ctxFactory)
{
_ctxFactory = ctxFactory;
}
#endregion
#region Public Methods
/// <inheritdoc />
public async Task<List<ConfigModel>> ConfigGetAllAsync()
{
await using var dbCtx = await _ctxFactory.CreateDbContextAsync();
return await dbCtx
.DbSetConfig
.AsNoTracking()
.OrderBy(x => x.Chiave)
.ToListAsync() ?? new();
}
/// <inheritdoc />
public async Task<List<MacchineModel>> MacchineGetAllAsync()
{
await using var dbCtx = await _ctxFactory.CreateDbContextAsync();
return await dbCtx
.DbSetMacchine
.AsNoTracking()
.OrderBy(x => x.IdxMacchina)
.ToListAsync() ?? new();
}
/// <inheritdoc />
public async Task<List<MacchineModel>> MacchineGetFiltAsync(string codGruppo)
{
await using var dbCtx = await _ctxFactory.CreateDbContextAsync();
List<MacchineModel> dbResult;
if (codGruppo == "*")
{
dbResult = await dbCtx
.DbSetMacchine
.AsNoTracking()
.OrderBy(x => x.IdxMacchina)
.ToListAsync();
}
else
{
dbResult = await dbCtx
.DbSetGrp2Macc
.Where(g => g.CodGruppo == codGruppo)
.Join(dbCtx.DbSetMacchine,
g => g.IdxMacchina,
m => m.IdxMacchina,
(g, m) => m
)
.AsNoTracking()
.OrderBy(x => x.IdxMacchina)
.ToListAsync();
}
dbResult = dbResult
.Where(x => !string.IsNullOrEmpty(x.locazione))
.OrderBy(x => x.locazione).ToList();
return dbResult;
}
/// <inheritdoc />
public async Task<List<MappaStatoExplModel>> MseGetAllAsync(int maxAge = 2000)
{
await using var dbCtx = await _ctxFactory.CreateDbContextAsync();
var maxAgeSec = new SqlParameter("@maxAgeSec", maxAge);
var dbResult = await dbCtx
.DbSetMSE
.FromSqlRaw("EXEC stp_MSE_getData @maxAgeSec", maxAgeSec)
.AsNoTracking()
.ToListAsync();
return dbResult;
}
#endregion
}
}
@@ -0,0 +1,15 @@
using MP.Data.DbModels;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace MP.Data.Repository.MpVoc
{
public interface IMpVocRepository
{
Task<List<ConfigModel>> ConfigGetAllAsync();
Task<List<LingueModel>> LingueGetAllAsync();
Task<List<VocabolarioModel>> VocabolarioGetAllAsync();
}
}
@@ -0,0 +1,63 @@
using Microsoft.EntityFrameworkCore;
using MP.Data.DbModels;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace MP.Data.Repository.MpVoc
{
public class MpVocRepository : IMpVocRepository
{
#region Private Fields
private readonly IDbContextFactory<MoonPro_VocContext> _ctxFactory;
#endregion
#region Public Constructors
public MpVocRepository(IDbContextFactory<MoonPro_VocContext> ctxFactory)
{
_ctxFactory = ctxFactory;
}
#endregion
#region Public Methods
/// <inheritdoc />
public async Task<List<ConfigModel>> ConfigGetAllAsync()
{
await using var dbCtx = await _ctxFactory.CreateDbContextAsync();
return await dbCtx
.DbSetConfig
.AsNoTracking()
.OrderBy(x => x.Chiave)
.ToListAsync() ?? new();
}
/// <inheritdoc />
public async Task<List<LingueModel>> LingueGetAllAsync()
{
await using var dbCtx = await _ctxFactory.CreateDbContextAsync();
return await dbCtx
.DbSetLilngue
.AsNoTracking()
.OrderBy(x => x.Lingua)
.ToListAsync() ?? new();
}
/// <inheritdoc />
public async Task<List<VocabolarioModel>> VocabolarioGetAllAsync()
{
await using var dbCtx = await _ctxFactory.CreateDbContextAsync();
return await dbCtx
.DbSetVocabolario
.AsNoTracking()
.OrderBy(x => x.Lemma)
.ToListAsync() ?? new();
}
#endregion
}
}
+10 -10
View File
@@ -21,8 +21,9 @@ namespace MP.Data.Services
{
#region Public Constructors
public LandDataService(IConfiguration configuration, IConnectionMultiplexer redConn) : base(configuration, redConn)
public LandDataService(IConfiguration configuration, IConnectionMultiplexer redConn, Repository.MpLand.IMpLandRepository mpLandRepository) : base(configuration, redConn)
{
_mpLandRepository = mpLandRepository;
// conf DB
string connStr = _configuration.GetConnectionString("MP.Land");
if (string.IsNullOrEmpty(connStr))
@@ -31,9 +32,8 @@ namespace MP.Data.Services
}
else
{
dbController = new Controllers.MpLandController(configuration);
StringBuilder sb = new StringBuilder();
sb.AppendLine($"LandService | MpLandController OK");
sb.AppendLine($"LandService | MpLandRepository OK");
Log.Info(sb.ToString());
}
}
@@ -69,7 +69,7 @@ namespace MP.Data.Services
}
else
{
result = dbController.AllDbInfo();
result = _mpLandRepository.AllDbInfoAsync().GetAwaiter().GetResult();
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
_redisDb.StringSet(currKey, rawData, UltraFastCache);
@@ -105,10 +105,10 @@ namespace MP.Data.Services
else
{
// recupero RRL missing
var listRRl = dbController.RemRebootLogGetLast();
var listRRlAdd = dbController.RemRebootLogGetLastNoMacc();
var listRRl = _mpLandRepository.RemRebootLogGetLastAsync().GetAwaiter().GetResult();
var listRRlAdd = _mpLandRepository.RemRebootLogGetLastNoMaccAsync().GetAwaiter().GetResult();
// recupero lista macchine
var ListMacch = dbController.MacchineGetAll();
var ListMacch = _mpLandRepository.MacchineGetAllAsync().GetAwaiter().GetResult();
// ...converto in DTO
dbResult = ListMacch
.Select(x => new IobDTO(x, IobInfo(x.IdxMacchina), MachIobConf(x.IdxMacchina)))
@@ -158,7 +158,7 @@ namespace MP.Data.Services
}
else
{
result = dbController.RemRebootLogGetAll();
result = _mpLandRepository.RemRebootLogGetAllAsync().GetAwaiter().GetResult();
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
_redisDb.StringSet(currKey, rawData, UltraFastCache);
@@ -194,7 +194,7 @@ namespace MP.Data.Services
}
else
{
result = dbController.RemRebootLogGetLast();
result = _mpLandRepository.RemRebootLogGetLastAsync().GetAwaiter().GetResult();
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
_redisDb.StringSet(currKey, rawData, UltraFastCache);
@@ -219,7 +219,6 @@ namespace MP.Data.Services
if (disposing)
{
// Free managed resources here
dbController.Dispose();
}
// Free unmanaged resources here
@@ -234,6 +233,7 @@ namespace MP.Data.Services
#region Private Fields
private readonly Repository.MpLand.IMpLandRepository _mpLandRepository;
private static Logger Log = LogManager.GetCurrentClassLogger();
private bool _disposed = false;
private string redisBaseKey = "MP:LAND:Cache";
+1 -1
View File
@@ -11,7 +11,7 @@ namespace MP.Data.Services
{
#region Public Constructors
public MonDataFeeder(IConfiguration configuration, IConnectionMultiplexer redConn) : base(configuration, redConn)
public MonDataFeeder(IConfiguration configuration, IConnectionMultiplexer redConn, Repository.MpMon.IMpMonRepository mpMonRepository) : base(configuration, redConn, mpMonRepository)
{
// setup canali pub/sub
dataPipe = new MessagePipe(redisConn, Constants.MON_ACT_MSE_DATA_KEY);
+9 -15
View File
@@ -1,6 +1,5 @@
using Microsoft.Extensions.Configuration;
using MP.Core.Conf;
using MP.Data.Controllers;
using MP.Data.DbModels;
using Newtonsoft.Json;
using NLog;
@@ -20,9 +19,10 @@ namespace MP.Data.Services
{
#region Public Constructors
public StatusData(IConfiguration configuration, IConnectionMultiplexer redConn)
public StatusData(IConfiguration configuration, IConnectionMultiplexer redConn, Repository.MpMon.IMpMonRepository mpMonRepository)
{
_configuration = configuration;
_mpMonRepository = mpMonRepository;
// setup componenti REDIS
this.redisConn = redConn;
@@ -42,9 +42,8 @@ namespace MP.Data.Services
}
else
{
dbController = new MpMonController(configuration);
StringBuilder sb = new StringBuilder();
sb.AppendLine($"StatusData | MpMonController OK");
sb.AppendLine($"StatusData | MpMonRepository OK");
Log.Info(sb.ToString());
}
@@ -70,8 +69,6 @@ namespace MP.Data.Services
#region Public Properties
public static MpMonController dbController { get; set; } = null!;
/// <summary>
/// Dizionario dei tag configurati per IOB
/// </summary>
@@ -102,7 +99,7 @@ namespace MP.Data.Services
}
else
{
result = dbController.ConfigGetAll();
result = await _mpMonRepository.ConfigGetAllAsync();
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, LongCache);
@@ -186,7 +183,7 @@ namespace MP.Data.Services
}
else
{
result = await Task.FromResult(dbController.MacchineGetAll());
result = await _mpMonRepository.MacchineGetAllAsync();
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
await redisDb.StringSetAsync(currKey, rawData, LongCache);
@@ -198,7 +195,6 @@ namespace MP.Data.Services
sw.Stop();
Log.Debug($"MacchineGetAll | {source} | {sw.Elapsed.TotalMilliseconds}ms");
return result;
//return Task.FromResult(dbController.MacchineGetAll());
}
public async Task<List<MacchineModel>> MacchineGetByGruppo(string CodGruppo)
@@ -217,8 +213,7 @@ namespace MP.Data.Services
}
else
{
result = await Task.FromResult(dbController.MacchineGetFilt(CodGruppo));
//result = dbController.MacchineGetFilt(CodGruppo);
result = await _mpMonRepository.MacchineGetFiltAsync(CodGruppo);
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
await redisDb.StringSetAsync(currKey, rawData, LongCache);
@@ -339,7 +334,7 @@ namespace MP.Data.Services
}
else
{
result = await dbController.MseGetAllAsync(maxAge);
result = await _mpMonRepository.MseGetAllAsync(maxAge);
// serializzp e salvo...
rawData = JsonConvert.SerializeObject(result);
await redisDb.StringSetAsync(Constants.redisMseKey, rawData, UltraFastCache);
@@ -383,8 +378,6 @@ namespace MP.Data.Services
MachineProdStatus.Clear();
// REDIS dispose
redisDb = null;
// Clear database controller
dbController.Dispose();
}
// Free unmanaged resources here
@@ -397,6 +390,7 @@ namespace MP.Data.Services
#region Private Fields
private static IConfiguration _configuration = null!;
private readonly Repository.MpMon.IMpMonRepository _mpMonRepository;
private static Logger Log = LogManager.GetCurrentClassLogger();
private bool _disposed = false;
@@ -512,7 +506,7 @@ namespace MP.Data.Services
if (fileConfData.IobSetup.ContainsKey("***"))
{
// recupero elenco macchine...
var elencoMacc = dbController.MacchineGetAll();
var elencoMacc = _mpMonRepository.MacchineGetAllAsync().GetAwaiter().GetResult();
// x ogni macchina creo le righe standard da conf...
var baseConf = fileConfData.IobSetup.Where(x => x.Key == "***").FirstOrDefault();
foreach (var item in elencoMacc)
+1 -1
View File
@@ -11,7 +11,7 @@ namespace MP.Data.Services
{
#region Public Constructors
public TabDataFeeder(IConfiguration configuration, IConnectionMultiplexer redConn) : base(configuration, redConn)
public TabDataFeeder(IConfiguration configuration, IConnectionMultiplexer redConn, Repository.MpMon.IMpMonRepository mpMonRepository) : base(configuration, redConn, mpMonRepository)
{
// setup canali pub/sub
dataPipe = new MessagePipe(redisConn, Constants.TAB_ACT_MSE_DATA_KEY, false);
+11 -15
View File
@@ -23,8 +23,9 @@ namespace MP.Data.Services
{
#region Public Constructors
public TranslateSrv(IConfiguration configuration, IConnectionMultiplexer redConn) : base(configuration, redConn)
public TranslateSrv(IConfiguration configuration, IConnectionMultiplexer redConn, Repository.MpVoc.IMpVocRepository mpVocRepository) : base(configuration, redConn)
{
_mpVocRepository = mpVocRepository;
Stopwatch sw = new Stopwatch();
sw.Start();
// conf DB
@@ -35,21 +36,15 @@ namespace MP.Data.Services
}
else
{
dbController = new Controllers.MpVocController(configuration);
var _ = _mpVocRepository.ConfigGetAllAsync().GetAwaiter().GetResult();
InitDict();
sw.Stop();
Log.Info($"TranslateSrv | MpVocController OK | {sw.Elapsed.TotalMilliseconds} ms");
Log.Info($"TranslateSrv | MpVocRepository OK | {sw.Elapsed.TotalMilliseconds} ms");
}
}
#endregion Public Constructors
#region Public Properties
public static Controllers.MpVocController dbController { get; set; } = null!;
#endregion Public Properties
#region Public Methods
/// <summary>
@@ -73,7 +68,7 @@ namespace MP.Data.Services
}
else
{
result = dbController.ConfigGetAll();
result = await _mpVocRepository.ConfigGetAllAsync();
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
_redisDb.StringSet(currKey, rawData, LongCache);
@@ -133,7 +128,7 @@ namespace MP.Data.Services
}
else
{
result = dbController.LingueGetAll();
result = await _mpVocRepository.LingueGetAllAsync();
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
_redisDb.StringSet(currKey, rawData, UltraLongCache);
@@ -185,7 +180,7 @@ namespace MP.Data.Services
}
else
{
result = dbController.VocabolarioGetAll();
result = await _mpVocRepository.VocabolarioGetAllAsync();
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
_redisDb.StringSet(currKey, rawData, UltraLongCache);
@@ -220,7 +215,6 @@ namespace MP.Data.Services
{
// Free managed resources here
DictVocab.Clear();
dbController.Dispose();
}
// Free unmanaged resources here
@@ -239,6 +233,8 @@ namespace MP.Data.Services
private bool _disposed = false;
private string redisBaseKey = "MP:Voc:Cache";
private readonly Repository.MpVoc.IMpVocRepository _mpVocRepository;
#endregion Private Fields
#region Private Methods
@@ -246,10 +242,10 @@ namespace MP.Data.Services
/// <summary>
/// Inizializzazione dict vari
/// </summary>
private static void InitDict()
private void InitDict()
{
// inizializzo dizionario vocabolario
var rawData = dbController.VocabolarioGetAll();
var rawData = _mpVocRepository.VocabolarioGetAllAsync().GetAwaiter().GetResult();
DictVocab = rawData.ToDictionary(kvp => $"{kvp.Lingua}_{kvp.Lemma}".ToUpper(), kvp => kvp.Traduzione);
}
-2
View File
@@ -235,7 +235,6 @@ namespace MP.SPEC.Data
);
}
#if false
/// <summary>
/// Elenco codice articoli che abbiano dati Dossier
/// </summary>
@@ -250,7 +249,6 @@ namespace MP.SPEC.Data
tagList: [Utils.redisArtByDossier]
);
}
#endif
/// <summary>
/// Conteggio articoli data ricerca
+72 -47
View File
@@ -1,55 +1,80 @@
# ?? Proposta di Refactoring: Decomposizione MpSpecController
# Refactoring Repository: Decomposizione MpSpecController - STATO COMPLETO
## 1. Situazione Attuale (AS-IS)
* **Componente**: MpSpecController (situato in MP.Data\Controllers\).
* **Pattern**: "God Object" / Monolithic Repository.
* **Problemi identificati**:
* **Violazione SRP**: Gestisce entità eterogenee (Anagrafiche, Produzione, Dossier, Configurazione, Log).
* **Naming**: Il suffisso Controller è fuorviante (indica un livello API, mentre il ruolo è di Repository).
* **Manutenibilità**: Elevato rischio di regressioni durante le modifiche a causa dell'accorpamento di logiche diverse.
* **Testabilità**: Difficoltà estrema nel mockare le dipendenze (molteplici DbContext e parametri di configurazione) in un unico oggetto.
* **Accoppiamento**: MpDataService dipende da un unico, enorme oggetto per ogni operazione di persistenza.
## Riepilogo
## 2. Situazione Proposta (TO-BE)
* **Trasformazione**: MpSpecController viene rinominato in MpSpecRepository (come fallback o hub centrale temporaneo) e poi progressivamente svuotato.
* **Nuova Architettura**: Introduzione di Repository specializzati per **Domini Logici**, ognuno con la propria interfaccia (I...Repository).
* **Iniezione delle Dipendenze**: MpDataService smetterà di iniettare un unico repository e inizierà a iniettare solo i moduli di cui ha realmente bisogno (es. IAnagRepository, IProductionRepository, ecc.).
* **Standardizzazione**: Ogni repository gestirà esclusivamente il proprio DbContext di riferimento.
| Progetto | Build | Errori |
|---|---|---|
| MP.Data | OK | 0 |
| MP.SPEC | OK | 0 |
## 3. Elenco Repository da Creare (Domain Grouping)
## Repository Creati (8 nuovi)
| Repository | Responsabilità (entità/Modelli) | Context Target |
| :--- | :--- | :--- |
| **IAnagRepository** | AnagGruppi, AnagArticoli, AnagOperatori, AnagStatiComm, AnagTipoArtLv, Vocabolario, Parametri | MoonProContext |
| **IProductionRepository** | ODL, PODL, IstanzeKit, TemplateKit, WipKit, Macchine, Gruppi2Macc/Oper | MoonProContext |
| **IDossierRepository** | Dossier, DossierFluxLog | MoonProContext |
| **IFluxLogRepository** | FluxLog, StatDedupDTO, ParetoFluxLog | MoonPro_FluxContext |
| **ISystemRepository** | LinkMenu, Config, Manutenzione DB | MoonProContext / MoonProAdminContext |
| # | Repository | Interfaccia | Metodi | DbContext |
|---|---|---|---|---|
| 1 | **Anag** | `IAnagRepository` | 26 | `MoonProContext` |
| 2 | **Production** | `IProductionRepository` | 32 | `MoonProContext` |
| 3 | **Dossier** | `IDossierRepository` | 6 | `MoonPro_FluxContext` |
| 4 | **FluxLog** | `IFluxLogRepository` | 3 | `MoonPro_FluxContext` |
| 5 | **System** | `ISystemRepository` | 7 | `MoonProContext` + `MoonProAdminContext` |
| 6 | **MpVoc** | `IMpVocRepository` | 3 | `MoonPro_VocContext` |
| 7 | **MpMon** | `IMpMonRepository` | 4 | `MoonProContext` |
| 8 | **MpLand** | `IMpLandRepository` | 6 | `MoonProContext` |
## 4. Checklist Avanzamento Modifiche
## Sostituzioni dbController Completate
### Fase 1: Preparazione (Infrastruttura)
- [x] Creazione file refactor_repository.md.
- [x] Analisi delle interfacce necessarie per ogni dominio.
- [x] Rinomina MpSpecController $\rightarrow$ MpSpecRepository (per allineamento naming).
| File Originale | Sostituito con | Chiamate | Stato |
|---|---|---|---|
| **MpDataService.cs** | 5 repository (Anag, System, Dossier, FluxLog, Production) | ~90 | Completato |
| **TranslateSrv.cs** | `IMpVocRepository` | 7 | Completato |
| **StatusData.cs** | `IMpMonRepository` | 10 | Completato |
| **LandDataService.cs** | `IMpLandRepository` | 9 | Completato |
| **OrderDataSrv.cs** | System + Production | 2 | Completato |
| **ListSelectDataSrv.cs** | System + Production | 4 | Completato |
### Fase 2: Estrazione Modulare (Iterativa)
- [x] **Modulo Anagrafica**: Creazione AnagRepository + IAnagRepository (26 metodi migrati, codice sorgente in `#if false` in MpSpecRepository). File: `MP.Data\Repository\Anag\`
- [x] **Modulo Produzione**: Creazione ProductionRepository + IProductionRepository (32 metodi migrati). File: `MP.Data\Repository\Production\`
- ODL: ListODLFiltAsync, OdlByKeyAsync, ODLCloseAsync, OdlGetCurrentAsync, OdlGetStatAsync, OdlByBatchAsync
- PODL: ListPODLFiltAsync, ListPODL_ByCodArtAsync, ListPODL_ByKitParentAsync, ListPODL_KitFiltAsync, PODL_getByKeyAsync, PODL_getByOdlAsync, PODL_getDictOdlPodlAsync, PODL_startSetup, PODL_updateRecipe, PODLDeleteRecordAsync, PODLUpdateRecordAsync, PodlIstKitDeleteAsync
- Kit: IstKitDeleteAsync, IstKitFiltAsync, IstKitInsertByWKSAsync, IstKitUpsertAsync, TemplateKitDeleteAsync, TemplateKitFiltAsync, TemplateKitUpsertAsync, WipKitDeleteAsync, WipKitDeleteOlderAsync, WipKitFiltAsync, WipKitUpsertAsync, TksScoreAsync
- Macchine/Gruppi: MacchineGetFiltAsync, MacchineByMatrOperAsync, MacchineWithFluxAsync, Grp2MaccDeleteAsync, Grp2MaccInsertAsync, Grp2OperDeleteAsync, Grp2OperInsertAsync
- Misc: MseGetAllAsync, ListGiacenzeAsync, OperatoriGetFiltAsync, ParametriGetFiltAsync
- [x] **Modulo Dossier**: Creazione DossierRepository + IDossierRepository (5 metodi migrati). File: `MP.Data\Repository\Dossier\`
- DossiersDeleteRecordAsync, DossiersGetLastFiltAsync, DossiersInsertAsync, DossiersTakeParamsSnapshotLastAsync, DossiersUpdateValoreAsync
- [x] **Modulo FluxLog**: Creazione FluxLogRepository + IFluxLogRepository (3 metodi migrati). File: `MP.Data\Repository\FluxLog\`
- FluxLogDataReduxAsync, FluxLogGetLastFiltAsync, FluxLogParetoAsync
- [x] **Modulo Sistema**: Creazione SystemRepository + ISystemRepository (7 metodi migrati). File: `MP.Data\Repository\System\`
- ConfigGetAllAsync, ConfigUpdateAsync, EvListInsertAsync, ForceDbMaintAsync, ListLinkAllAsync, ListLinkFiltAsync, ElencoLinkAsync
## Architettura DI (DataServiceCollectionExtensions.cs)
### Fase 3: Pulizia e Verifica
- [ ] **Passo 3.1**: Spostamento a `#if false` dei metodi migrati in MpSpecRepository (33 metodi originali ancora attivi).
- [ ] **Passo 3.2**: Verifica compilazione (dotnet build MP.Data\MP.Data.csproj).
- [ ] **Passo 3.3**: Aggiornamento MpDataService per iniettare i 5 nuovi repository invece di MpSpecRepository.
- [ ] **Passo 3.4**: Refactoring MpSpecRepository (solo metodi residui non migrati).
```csharp
// Repository Scoped
services.TryAddScoped<IAnagRepository, AnagRepository>();
services.TryAddScoped<IProductionRepository, ProductionRepository>();
services.TryAddScoped<IDossierRepository, DossierRepository>();
services.TryAddScoped<IFluxLogRepository, FluxLogRepository>();
services.TryAddScoped<ISystemRepository, SystemRepository>();
services.TryAddScoped<IMpMonRepository, MpMonRepository>();
services.TryAddScoped<IMpVocRepository, MpVocRepository>();
services.TryAddScoped<IMpLandRepository, MpLandRepository>();
```
## File Modificati
- `MP.Data/DataServiceCollectionExtensions.cs` (+10/-1)
- `MP.Data/Services/LandDataService.cs` (+10/-10)
- `MP.Data/Services/MonDataFeeder.cs` (+1/-1)
- `MP.Data/Services/StatusData.cs` (+12/-12)
- `MP.Data/Services/TabDataFeeder.cs` (+1/-1)
- `MP.Data/Services/TranslateSrv.cs` (+13/-13)
- `MP.SPEC/Data/MpDataService.cs` (+1/-3)
## File Nuovi (6)
- `MP.Data/Repository/MpLand/IMpLandRepository.cs`
- `MP.Data/Repository/MpLand/MpLandRepository.cs`
- `MP.Data/Repository/MpMon/IMpMonRepository.cs`
- `MP.Data/Repository/MpMon/MpMonRepository.cs`
- `MP.Data/Repository/MpVoc/IMpVocRepository.cs`
- `MP.Data/Repository/MpVoc/MpVocRepository.cs`
## Verifiche
- Nessun riferimento a `dbController.XXX()` nei file di servizio
- `ArticleWithDossierAsync` esportato correttamente (rimossi `#if false`)
- `VocabolarioGetLang` reso sincrono (firma originale sincrona)
- `tryLoadIobTags` in StatusData usa `GetAwaiter().GetResult()` (contesto sync)
- `InitDict` in TranslateSrv usa `GetAwaiter().GetResult()` (contesto sync)
## MpSpecRepository (MpSpecController)
I metodi原价 sono ancora visibili nel file ma:
- Non sono usati dai layer superiori (tutti migrati ai repository)
- Possono essere spostati a `#if false` come ultima fase di pulizia
- Rimangono come fallback documentato