Dal tema della rivista alla pratica di progetto
Pagine di servizi e tecniche correlate all'articolo
In molte divisioni IT la situazione di partenza è simile: un’applicazione desktop Delphi stabile e vicina ai processi sostiene attività critiche, mentre nuove esigenze spingono verso il web, i portali, l’uso mobile e l’integrazione con servizi cloud. Allo stesso tempo C# è adottato in molte aziende quando si tratta di servizi, Web-API e integrazione delle identità. La domanda centrale non è quindi più „Delphi o C#?“, ma: combinare C# e Delphi in un’architettura comune in modo che esercizio, manutenzione, gestione dei dati e sicurezza restino governabili.
Questo contributo descrive principi architetturali praticabili che si sono dimostrati validi in contesti aziendali dove non tutto può o deve essere ricostruito da zero. Il focus è su responsabilità chiare tra client desktop, servizi, dati e interfacce – e su come pianificare passaggi di modernizzazione a basso rischio senza compromettere i processi in esercizio.
Perché gli stack misti sono la norma nelle aziende
Le soluzioni digitali aziendali cresciute nel tempo raramente nascono su terreno vergine. Le applicazioni Delphi sono spesso state estese per molti anni, vicino ai processi di business, con logiche dati estese e profonda conoscenza dei casi particolari. Parallelamente sono emerse nuove esigenze: portali self-service, scambi di dati automatizzati, integrazione con DMS/CRM/ERP, multi-tenancy, maggiore auditabilità o Single Sign-on.
C# offre in questo contesto spesso vantaggi negli ecosistemi Web e di servizi: ampio spettro di hosting, middleware standardizzate, buona integrazione con Identity Provider e pattern consolidati per le Web-API. Delphi rimane invece forte quando si tratta di client desktop Windows performanti, applicazioni VCL mantenute a lungo termine o client multipiattaforma specifici (es. via FMX).
La combinazione quindi non è un „caso particolare“, ma una risposta realistica a protezione degli investimenti e alla pressione per la modernizzazione. È cruciale che l’operatività congiunta non si trasformi in un cantiere permanente.
Principio architetturale: strati chiari anziché confini basati sul linguaggio
Quando si incontrano due linguaggi, la tentazione è grande di organizzare la separazione lungo la tecnologia („Tutto Delphi è Legacy, tutto C# è nuovo“). Tecnicamente questo spesso funziona nel breve termine, ma a lungo andare genera attriti: regole di business duplicate, responsabilità poco chiare ed errori difficili da riprodurre.
Si è invece dimostrata valida una stratificazione funzionale, spesso realizzata come Layer-3 Architektur: presentazione (UI), dominio (logica di business) e infrastruttura (accesso ai dati, sistemi esterni). Il punto non è il modello da manuale, ma l’effetto concreto nella pratica quotidiana: decisioni su dati, validazioni e workflow vengono prese in un punto centrale e rese disponibili tramite interfacce stabili.
In un’architettura mista questo significa praticamente: Delphi può continuare a fornire una parte UI (o determinati workflow), mentre C# Services possono incapsulare uno strato di dominio funzionale – o viceversa. È importante che il confine tra gli strati sia tecnicamente pulito e testabile.
C# e Delphi in un’architettura comune: tre pattern di integrazione collaudati
Per il collegamento tra Delphi e C# non esiste un unico percorso “corretto”. Buone decisioni si basano su requisiti di esercizio, sicurezza, latenza, volume dei dati e cicli di rilascio. Nella pratica si sono affermati tre modelli.
1) Orientamento ai servizi tramite HTTP/REST come integrazione standard
La soluzione più robusta per esercizio e evoluzione è spesso il collegamento tramite API REST (interfacce basate su HTTP). I client di Delphi invocano servizi di C# o di Delphi; i portali di C# utilizzano gli stessi endpoint. Questo disaccoppiamento rende i rilasci più prevedibili: un aggiornamento del client non è sempre necessario se l’API rimane retrocompatibile.
Importante è la cura professionale dell’implementazione: timeout, retry, idempotenza (richieste ripetibili senza effetti collaterali), codici di errore chiari e una strategia di versionamento. Per amministrazione e operation contano inoltre: log uniformi, ID di richiesta tracciabili e tempi di risposta ben misurabili.
2) Database condiviso: solo con regole chiare
L’accesso a un database condiviso da parte di Delphi e C# può essere allettante perché inizialmente veloce. Sul lungo periodo però è rischioso se entrambi i mondi scrivono direttamente sugli stessi insiemi di tabelle. Il motivo: le regole di business migrano in trigger, stored procedure o “da qualche parte nel client”. Questo complica l’analisi degli errori e le verifiche di audit.
Se un database condiviso è inevitabile (es. in fasi di transizione), aiutano regole chiare:
- Centralizzare gli accessi in scrittura: un sistema è «System of Record» per determinate entità.
- Definire contratti: view o API come livello di lettura stabile invece di accessi diretti alle tabelle.
- Pianificare finestre di migrazione: distribuire le modifiche al database sempre in modo retrocompatibile (es. nuove colonne prima opzionali).
Tecnicamente il database diventa allora un componente infrastrutturale, non il bus di integrazione.
3) Messaging/Eventi per processi asincroni
Per flussi disaccoppiati (es. operazioni di import, notifiche, post-elaborazione, job di interfaccia) un modello asincrono è efficace: un sistema pubblica eventi, un altro li elabora. Questo riduce le dipendenze dirette e stabilizza i picchi di carico.
Per la direzione IT e gli amministratori sono rilevanti: monitoring (lunghezze delle code), concetti di dead-letter (messaggi non consegnati), meccanismi di ripetizione e chiara idempotenza a livello funzionale. Gli eventi non sostituiscono una gestione pulita dei dati anagrafici, ma sono uno strumento efficace per catene di processo robuste.
Contratti dati e compatibilità: il nucleo spesso sottovalutato
A prescindere dal modello di integrazione, la qualità dei contratti dati determina la stabilità. Un contratto dati è la descrizione vincolante di campi, tipi, obbligatorietà/opzionalità e semantica. Nelle API REST questo è tipicamente JSON; l’importante non è «JSON in sé», ma la disciplina nella gestione delle modifiche.
Regole consolidate che semplificano concretamente l’operatività:
- Estendere invece di rompere: aggiungere nuovi campi, continuare a fornire quelli esistenti almeno inizialmente.
- Documentare la semantica dei campi: non solo «string», ma per esempio formato data ISO, fuso orario, stati ammessi.
- Trattare gli enum in modo tollerante: i client devono sopravvivere a valori sconosciuti (compatibilità in avanti).
- Applicare consapevolmente il versionamento delle API: non ogni rilascio richiede una nuova versione; tuttavia le modifiche incompatibili devono essere chiaramente isolate.
Questi punti sono particolarmente importanti quando i client desktop Delphi non possono essere aggiornati con la stessa frequenza dei servizi web.
Autenticazione e autorizzazione: un modello di sicurezza condiviso
Le architetture miste raramente falliscono per la «tecnica», più spesso per una sicurezza incoerente. Per l’azienda conta: chi può fare cosa? Come viene verificato? Come viene auditato? Un modello condiviso evita la duplicazione della gestione utenti e ruoli contrastanti.
Nella pratica ciò porta a uno strato di identità centrale: ad esempio tramite SAML 2.0 (Single Sign-on federato, frequente in ambito enterprise) o OpenID Connect (basato su OAuth2, spesso per moderne Web-API). C#-Services si possono in genere collegare direttamente a un Identity Provider; Delphi-client possono ottenere token e inviarli nelle chiamate API. È importante che anche le applicazioni desktop non ricevano «privilegi speciali» tramite accesso diretto al database.
Centrali per gli amministratori:
- Durata dei token e strategia di refresh (in modo che i client funzionino in modo stabile e rimangano comunque sicuri)
- Autenticazione service-to-service per la comunicazione interna (p. es. mTLS o token firmati)
- Least Privilege: non definire ruoli e permessi in modo troppo ampio
- Audit-Logs: registrare in modo tracciabile le azioni rilevanti per la sicurezza
Concetti operativi: Windows- e Linux-Services, IIS e processi nella pratica quotidiana
Un’architettura è in azienda «buona» solo se è gestibile: aggiornamenti pianificabili, errori localizzabili, carico gestibile. In ambienti misti le varianti operative più comuni sono:
- Windows- und Linux-Services: adatti per job in background, esecuzioni di interfacce, worker; ben integrabili nei modelli operativi classici basati su server Windows.
- Windows- und Linux-Services/Daemon: sensati per modelli operativi containerizzati o basati su VM; spesso stabili in esercizio continuativo, con buona automazione tramite systemd.
- Microsoft IIS: hosting consolidato per applicazioni web e scenari di reverse-proxy in ambienti centrati su Windows.
È importante che Delphi- e C#-componenti soddisfino standard operativi simili: endpoint di health coerenti (segnali di vita), timeout definiti, consumo di risorse limitato, nonché una procedura chiara di deployment e rollback. Questo riduce i trattamenti speciali ’specifici per la tecnologia‘.
Logging, Tracing und Metriken: ein gemeinsames Observability-Niveau
Particolarmente con due stack tecnologici sono decisive catene di diagnostica end-to-end. Un problema tipico: il client Delphi segnala «errore nel salvataggio», il servizio C# ha un timeout, il database segnala lock – senza una correlazione comune.
Si sono dimostrate efficaci:
- ID di correlazione per richiesta (Client → API → DB), in modo che i log possano essere aggregati.
- Logging strutturato (chiave/valore invece di semplici linee di testo), per consentire filtraggi successivi.
- Metriche per latenza, tassi di errore, lunghezze delle code e utilizzo delle risorse.
- Classificazione degli errori: errori di business (validazione) separati dagli errori tecnici (timeout, rete).
Questi principi fanno risparmiare nella pratica più tempo di qualsiasi discussione sulla „lingua giusta“.
Accesso ai dati e migrazione: BDE-sostituzione, FireDAC e database moderni
Negli ambienti Delphi l’accesso ai dati ha storicamente un ruolo importante. Dove sono ancora in uso vie di accesso obsolete come la Borland Database Engine (BDE), si crea pressione aggiuntiva: aggiornamenti del sistema operativo, migrazioni a 64 bit, disponibilità dei driver, requisiti di sicurezza. Una BDE-Ablösung non è quindi solo modernizzazione, ma riduzione del rischio.
Tipico è il passaggio a una BDE-Ablösung mit nativer Anbindung (layer di accesso ai dati moderno in Delphi), combinato con un database operativamente gestibile (es. PostgreSQL, SQL Server, MariaDB). Per un’architettura comune Delphi/C# sono importanti due aspetti:
- Confini delle transazioni: chi avvia/esegue il commit delle transazioni e come vengono regolati gli accessi in scrittura paralleli?
- Strategia di locking e isolamento: in modo che i workflow desktop e i servizi non si blocchino a vicenda.
Nelle migrazioni è efficace una pianificazione a fasi: prima modernizzare driver e livello di accesso, poi consolidare il modello dati, successivamente stabilizzare le interfacce di integrazione. Così le fonti di errore diventano isolabili e i rollback realistici.
Release-Management: conciliare cicli di aggiornamento diversi
Un’area di tensione ricorrente è la frequenza degli aggiornamenti: i web service possono essere distribuiti più spesso, i client desktop spesso meno (finestre di rollout, comunicazione agli utenti, impacchettamento). Un’architettura comune deve tenere conto di questa asimmetria.
Conseguenze pratiche:
- Retrocompatibilità delle API è obbligatoria, non opzionale.
- Feature Flags (interruttori funzionali) aiutano ad attivare nuove funzionalità in modo controllato lato server.
- Le migrazioni dello schema devono avvenire per fasi: prima estendere il database, poi farle utilizzare dal servizio, quindi aggiornare il client.
- Deprecazione chiara: eliminare vecchi endpoint o campi solo dopo un periodo definito.
Soprattutto in ambienti regolamentati è importante fissare per iscritto queste regole come linee guida architetturali, in modo che le decisioni non vengano reinventate progetto per progetto.
Ostacoli tipici e come evitarli sistematicamente
Dal punto di vista operativo, i problemi più frequenti nelle infrastrutture miste Delphi/C# sono ben prevedibili. Se affrontati precocemente, i costi a lungo termine diminuiscono in modo significativo.
Ostacolo 1: logica di business duplicata
Se il client Delphi e il servizio C# implementano le stesse regole in modi diversi, nascono „errori fantasma“: un processo funziona nell’interfaccia utente, ma fallisce all’import tramite API. Contromisura: centralizzare le regole nello strato di dominio (servizio) o assegnarle chiaramente dal punto di vista funzionale, inclusi riscontri di validazione inequivocabili.
Ostacolo 2: workaround nell’UI invece di interfacce pulite
„Scriviamo rapidamente un campo nel database“ può sembrare innocuo nel singolo caso, ma genera interfacce ombra senza logging, autenticazione e versioning. Meglio: passare sistematicamente attraverso endpoint definiti, anche se inizialmente richiede più disciplina.
Ostacolo 3: responsabilità operative non chiare
Se non è chiaro quale team è responsabile di quale servizio, quale log e quali parametri operativi, la ricerca dei guasti finisce in ping-pong. Praticamente aiuta una mappa dei servizi (quale servizio, quali dipendenze, quali porte, quali SLA interni) e runbook unificati per le anomalie ricorrenti.
Punto critico 4: mancanza di coerenza nella sicurezza
Un portale con SSO, ma un client desktop con account amministratore locali è in molti audit un problema. Un modello comune di identità e ruoli riduce il rischio e il carico di supporto.
Guida alla decisione: cosa rimane in Delphi, cosa va in C#?
La ripartizione sensata dipende meno dall’ideologia che dalla prossimità ai processi e dai requisiti operativi. Come orientamento dal punto di vista dell’architettura e delle operazioni:
- Delphi è spesso adatto per: client desktop esistenti Windows-Desktop-Clients (VCL), workflow UI molto reattivi, scenari quasi offline, manutenzione a lungo termine di interfacce consolidate.
- C# è spesso adatto per: API centrali REST, servizi di integrazione verso ERP/DMS/CRM, componenti legate all’identità, portali e processi backend con alta frequenza di cambiamento.
- Decidere consapevolmente: la logica dei dati e la validazione non dovrebbero risiedere “nel client” se esistono più frontend (desktop, portale, job di importazione).
Importante: l’obiettivo non è “tutto verso C#”, ma un’architettura complessiva solida, in cui i passi di modernizzazione siano pianificabili e i processi aziendali rimangano stabili.
Percorso di modernizzazione: passo dopo passo dall’applicazione al sistema
Nella pratica un’architettura condivisa è spesso una fase di transizione, ma lunga. Un percorso di modernizzazione realistico evita grandi progetti ad alto rischio e punta su obiettivi intermedi misurabili:
- Stabilizzare le interfacce: introdurre l’API REST come confine funzionale, anche se internamente non è ancora tutto „pulito“.
- Modernizzare l’accesso ai dati: BDE-sostituzione, driver, compatibilità a 64 bit, transazioni chiare.
- Centralizzare l’identità: SSO e modello di ruoli per tutte le modalità di accesso.
- Unificare le operazioni: Logging/Monitoring/Health, deploy chiari, ambienti riproducibili.
- Disaccoppiare i moduli funzionali: spostare in servizi le parti soggette a frequenti modifiche, snellire gradualmente l’UI.
Quest’ordine non è dogmatico, ma riduce tipicamente le dipendenze: senza interfacce stabili e un concetto operativo, ogni ulteriore modifica diventa più costosa.
Conclusione: l’integrazione è una questione di architettura, non di linguaggi
Una combinazione sostenibile di Delphi e C# non nasce da „librerie ponte“, ma da confini funzionali chiari, contratti di dati puliti e un concetto operativo che prenda sul serio monitoring, sicurezza e gestione delle release. Se C# e Delphi in un’architettura comune cooperano consapevolmente lungo le responsabilità, le aziende ottengono soprattutto una cosa: modernizzazione senza interruzione dei processi. Delphi può continuare a sostenere in modo affidabile i workflow desktop stabili, mentre i servizi C# forniscono integrazione, Web-APIs e portali come funzionalità centrali della piattaforma.
Se desiderate modernizzare gradualmente un paesaggio Delphi esistente o collegare correttamente servizi C#, una review architetturale con focus su interfacce, dati, operazioni e sicurezza è la via più rapida per decisioni solide. Per saperne di più in un confronto diretto:
Nel contesto specialistico rivestono anche un ruolo importante la Delphi modernizzazione e l’REST-API per il software esistente, quando integrazioni, flussi di dati e l’ulteriore sviluppo devono integrarsi in modo coerente.
Discutere progetto o intervento di modernizzazione con Net-Base.
Passo successivo
Quando un tema diventa un progetto reale, architettura, sistemi esistenti e gestione operativa dovrebbero essere considerati insieme fin dalle fasi iniziali.
Non forniamo solo supporto per questioni isolate, ma anche quando da frammenti di codice sorgente, tematiche legacy o idee di portale deve nascere un progetto aziendale solido.
- Stato attuale, stato obiettivo e rischi tecnici vengono valutati insieme.
- REST, l'accesso ai dati, i portali e il rollout non vengono rinviati a fasi successive.
- Vede in anticipo quale percorso è economicamente e operativamente sostenibile.