Net-Base Rivista

07.06.2026

C# e Delphi in un'architettura condivisa: integrazione pragmatica anziché un approccio tutto-o-niente

Molte aziende gestiscono applicazioni desktop consolidate Delphi e costruiscono parallelamente nuovi servizi e portali C#. L'articolo mostra come C# e Delphi si integrino in modo ordinato in un'architettura comune: tramite strati chiari, interfacce stabili, componenti condivisi...

07.06.2026

Dal tema della rivista alla pratica di progetto

Pagine di servizi e tecniche correlate all'articolo

In molti reparti IT la situazione di partenza è simile: un’applicazione desktop Delphi stabile e vicina ai processi sostiene flussi critici, mentre nuove esigenze spingono verso web, portali, utilizzo mobile e integrazione con servizi cloud. Contemporaneamente 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: come combinare C# e Delphi in un’architettura comune in modo che esercizio, manutenzione, gestione dei dati e sicurezza rimangano gestibili.

Questo contributo descrive principi architetturali pratici e collaudati negli ambienti aziendali in cui 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 passi di modernizzazione a basso rischio senza mettere a rischio i processi in corso.

Perché gli stack misti sono la norma nelle aziende

Soluzioni digitali aziendali cresciute nel tempo raramente nascono su carta bianca. Le applicazioni Delphi sono spesso state estese per anni, vicine ai processi di business, con logica dati estesa e profonda conoscenza dei casi particolari. Parallelamente sono emerse nuove esigenze: portali self-service, scambi di dati automatizzati, collegamento a DMS/CRM/ERP, supporto multi-tenant, maggiore auditabilità o Single Sign-on.

In questo contesto C# offre spesso vantaggi per ecosistemi web e di servizio: ampia scelta di hosting, middleware standardizzato, buona integrazione con Identity Provider e pattern consolidati per le Web-API. Delphi rimane invece forte quando si tratta di client desktop performanti basati su Windows, di applicazioni VCL mantenute a lungo termine o di client multipiattaforma specifici (p.es. via FMX).

La combinazione non è quindi un „caso particolare“, ma una risposta realistica alla protezione degli investimenti e alla pressione di modernizzazione. Decisivo è che il funzionamento congiunto non diventi un cantiere permanente.

Principio architetturale: strati chiari invece di confini basati sulla lingua

Quando si combinano due linguaggi, la tentazione è grande di organizzare la separazione lungo la tecnologia („Tutto ciò che è Delphi è legacy, tutto ciò che è C# è nuovo“). Tecnicamente questo può funzionare 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 implementata come Layer-3 architettura: presentazione (UI), dominio (logica di business) e infrastruttura (accesso ai dati, sistemi esterni). L’importante non è il modello da libro di testo, ma l’effetto concreto nella pratica: decisioni su dati, validazioni e workflow vengono prese in un unico luogo e rese disponibili tramite interfacce stabili.

In un’architettura mista ciò significa praticamente: Delphi può continuare a fornire una parte UI (o determinati workflow), mentre C# Services incapsulano 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 l’accoppiamento di Delphi e C# non esiste ‚unica‘ via corretta. Buone decisioni si basano sull’operatività, sui requisiti di sicurezza, sulla latenza, sul volume dei dati e sui cicli di rilascio. In pratica si sono delineati tre modelli.

1) Orientamento ai servizi tramite HTTP/REST come collegamento standard

Spesso il più robusto per esercizio e evoluzione è un collegamento tramite REST-APIs (interfacce basate su HTTP). I client di Delphi invocano servizi di C# o di Delphi; i portali di C# utilizzano gli stessi endpoint. Questa disaccoppiamento rende i rilascî più pianificabili: un aggiornamento del client non è necessariamente richiesto se l’API rimane retrocompatibile.

Importante è una realizzazione professionale: timeouts, retries, idempotenza (richieste ripetibili senza effetti collaterali), codici di errore chiari e una strategia di versionamento. Per amministrazione e gestione operativa contano inoltre: log uniformi, request-ID tracciabili e tempi di risposta misurabili in modo affidabile.

2) Database condiviso: solo con regole chiare

L’accesso a un database condiviso da Delphi e C# può essere invitante perché inizialmente rapido. A lungo termine però è rischioso se entrambi i mondi scrivono direttamente sullo stesso insieme di tabelle. Il motivo: le regole di business si spostano 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 (p.es. in fasi di transizione), aiutano regole chiare:

  • Centralizzare gli accessi in scrittura: un sistema è ‚System of Record‘ per determinate entità.
  • Definire contratti: Views o API come layer di lettura stabile invece di accessi diretti alle tabelle.
  • Pianificare finestre di migrazione: distribuire le modifiche al database sempre in modo retrocompatibile (p.es. nuove colonne inizialmente opzionali).

Tecnicamente il database diventa allora un componente infrastrutturale, non il bus di integrazione.

3) Messaging/Events per processi asincroni

Per flussi disaccoppiati (p.es. import batch, notifiche, post-processing, job di interfaccia) è sensato un modello asincrono: 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 falliti), comportamento di riavvio e chiara idempotenza a livello di dominio. Gli eventi non sostituiscono una gestione accurata dei dati master, ma sono uno strumento efficace per catene di processo robuste.

Contratti di dati e compatibilità: il nucleo sottovalutato

Indipendentemente dal pattern di integrazione, la qualità dei contratti di dati determina la stabilità. Un contratto di dati è la descrizione vincolante di campi, tipi, obbligatorietà/opzionalità e semantica. Nelle REST-APIs questo è tipicamente JSON; ciò che conta non è ‚JSON in sé‘, ma la disciplina nella gestione delle modifiche.

Regole consolidate che semplificano sensibilmente l’operatività:

  • Estendere invece di rompere: aggiungere nuovi campi, continuare a fornire quelli esistenti.
  • Documentare la semantica dei campi: non solo ’string‘, ma p.es. data ISO, fuso orario, stati ammessi.
  • Trattare i valori enum con tolleranza: i client devono sopravvivere a valori sconosciuti (Forward-Compatibility).
  • Usare consapevolmente il versionamento delle API: non ogni rilascio richiede una nuova versione; le Breaking Changes devono però essere chiaramente isolate.

Questi punti sono particolarmente importanti quando i client desktop di Delphi non possono essere aggiornati con la stessa frequenza dei servizi web.

Autenticazione e autorizzazione: un modello di sicurezza condiviso

Le architetture miste falliscono raramente per «tecnica», più spesso per una sicurezza incoerente. Per l’azienda conta: chi può fare cosa? Come viene verificato? Come viene sottoposto ad audit? Un modello condiviso evita una gestione utenti duplicata e ruoli contraddittori.

Nella pratica questo porta a uno strato di identità centralizzato: ad esempio tramite SAML 2.0 (single sign-on federato, comune in ambito enterprise) o OpenID Connect (basato su OAuth2, spesso per moderne Web-API). C#-Services possono in genere essere collegati direttamente a un Identity Provider; Delphi-Client possono ottenere token e inviarli nelle chiamate API. È importante che anche le applicazioni desktop non ottengano «privilegi speciali» tramite accesso diretto al database.

Centrale per gli amministratori:

  • Durata dei token e strategia di refresh (affinché i client funzionino stabilmente mantenendo la sicurezza)
  • Autenticazione service-to-service per la comunicazione interna (p. es. mTLS o token firmati)
  • Least Privilege: non definire ruoli e permessi in modo troppo generico
  • Audit-Logs: registrare in modo tracciabile le azioni rilevanti per la sicurezza

Concetti operativi: Windows- und Linux-Services, IIS und Prozesse im Alltag

Un’architettura è per l’azienda «buona» solo se è gestibile: aggiornamenti pianificabili, errori localizzabili, carico controllabile. In ambienti eterogenei le varianti operative più comuni sono:

  • Windows- und Linux-Services: adatti per background job, esecuzioni di interfaccia, worker; ben integrabili nei modelli operativi tradizionali dei server Windows.
  • Windows- und Linux-Services/Daemon: sensati per modelli operativi containerizzati o basati su VM; spesso stabili in esercizio continuo, buona automazione tramite systemd.
  • Microsoft IIS: hosting consolidato per applicazioni web e scenari di reverse proxy in ambienti centrati su Windows.

È importante che i componenti Delphi e C# rispettino standard operativi simili: Health-Endpoints 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 tecnologia».

Logging, Tracing und Metriken: ein gemeinsames Observability-Niveau

Soprattutto con due stack tecnologici, catene di diagnosi end-to-end sono decisive. Un problema tipico: il client Delphi segnala «Errore durante il salvataggio», il servizio C# ha un timeout, il database segnala blocchi – senza una correlazione comune.

Sono pratiche consolidate:

  • ID di correlazione per richiesta (Client → API → DB), in modo che i log possano essere correlati.
  • Logging strutturato (chiave/valore invece di sole righe di testo), per poter filtrare in seguito.
  • 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).

Queste basi 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 rilevante. Quando sono ancora in uso vie di accesso obsolete come la Borland Database Engine (BDE), si crea una pressione aggiuntiva: aggiornamenti del sistema operativo, migrazioni a 64 bit, disponibilità dei driver, requisiti di sicurezza. Una sostituzione di BDE non è quindi solo modernizzazione, ma riduzione del rischio.

Tipico è il passaggio a una sostituzione di BDE con integrazione nativa (strato di accesso ai dati moderno in Delphi), combinata 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 gestiti gli accessi in scrittura paralleli?
  • Strategia di locking e isolamento: affinché i workflow desktop e i servizi non si blocchino a vicenda.

Nelle migrazioni è efficace una pianificazione a fasi: prima modernizzare driver e strato di accesso, poi consolidare il modello dati, quindi stabilizzare le interfacce di integrazione. In questo modo le cause di errore diventano isolabili e i rollback realistici.

Release-Management: conciliare cicli di aggiornamento diversi

Un campo di tensione ricorrente è la frequenza degli aggiornamenti: i web service possono essere rilasciati più frequentemente, i client desktop spesso meno (finestre di rollout, comunicazione agli utenti, confezionamento). Un’architettura condivisa 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 di schema devono avvenire in fasi: prima estendere il database, poi utilizzare il servizio, infine aggiornare il client.
  • Deprecation chiara: rimuovere endpoint o campi obsoleti solo dopo un periodo definito.

Soprattutto in ambienti regolamentati è importante fissare queste regole per iscritto come linee guida architetturali, in modo che le decisioni non vengano reinventate progetto per progetto.

Trappole tipiche e come evitarle sistematicamente

Dal punto di vista operativo i problemi più frequenti in paesaggi misti Delphi/C# sono ben prevedibili. Se affrontati precocemente, i costi a lungo termine scendono sensibilmente.

Problema 1: logica di business duplicata

Se il client Delphi e il service C# implementano le stesse regole in modo differente, nascono “errori fantasma”: un processo funziona nell’interfaccia utente, ma fallisce durante l’importazione via API. Contromisura: centralizzare le regole nello strato di dominio (service) o assegnarle chiaramente dal punto di vista funzionale, incluse risposte di validazione univoche.

Problema 2: workaround UI invece di interfacce pulite

“Giusto scriviamo rapidamente un campo nel database” può sembrare innocuo a caso singolo, ma genera interfacce ombra senza logging, autenticazione e versioning. Meglio: passare coerentemente tramite endpoint definiti, anche se inizialmente richiede più disciplina.

Problema 3: responsabilità operative poco chiare

Se non è chiaro quale team sia responsabile di quale servizio, di quale log e di 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 uniformi per le interruzioni frequenti.

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 l’onere del supporto.

Guida alla decisione: cosa rimane in Delphi, cosa va in C#?

La suddivisione sensata dipende meno dall’ideologia che dalla prossimità ai processi e dai requisiti operativi. Come orientamento dal punto di vista architetturale e operativo:

  • Delphi è spesso adatto per: client desktop Windows esistenti (VCL), workflow UI molto reattivi, scenari con requisiti di funzionamento offline, manutenzione a lungo termine di interfacce consolidate.
  • C# è spesso adatto per: API centrali REST, servizi di integrazione verso ERP/DMS/CRM, componenti legati all’identità, portali e processi backend con elevata frequenza di modifiche.
  • Decidere consapevolmente: la logica dei dati e la validazione non dovrebbero risiedere «nel client» quando esistono più frontend (desktop, portale, job di importazione).

Importante: l’obiettivo non è «tutto su C#», ma un’architettura complessiva solida, in cui i passi di modernizzazione siano pianificabili e i processi aziendali funzionino in modo stabile.

Percorso di modernizzazione: passo dopo passo dall’applicazione al sistema

Nella pratica un’architettura comune è spesso una transizione, ma lunga. Un percorso di modernizzazione realistico evita grandi progetti ad alto rischio e punta su obiettivi intermedi misurabili:

  1. Stabilizzare le interfacce: introdurre l’API REST come confine funzionale, anche se internamente non è ancora tutto «rifinito».
  2. Modernizzare l’accesso ai dati: BDE-sostituzione, driver, compatibilità 64-bit, gestione delle transazioni definita.
  3. Centralizzare l’identità: SSO e modello di ruoli per tutte le modalità di accesso.
  4. Uniformare il funzionamento: Logging/Monitoring/Health, deployment chiari, ambienti riproducibili.
  5. Disaccoppiare i moduli funzionali: trasferire in servizi le parti soggette a frequenti modifiche, snellire gradualmente l’UI.

Questa sequenza non è dogmatica, ma normalmente minimizza le dipendenze: senza interfacce stabili e un concetto operativo, ogni ulteriore modifica diventa più costosa.

Conclusione: l’integrazione è un compito architetturale, non una questione di linguaggi

Una combinazione sostenibile di Delphi e C# non nasce da «librerie ponte», ma da confini funzionali chiari, contratti di dati definiti e un concetto operativo che prende sul serio monitoring, sicurezza e gestione delle release. Se C# e Delphi in una comune architettura cooperano in modo consapevole lungo linee di responsabilità, le aziende ottengono soprattutto una cosa: modernizzazione senza rottura dei processi. Delphi può continuare a garantire workflow desktop stabili e affidabili, mentre i servizi C# forniscono integrazione, API Web e portali come funzioni centrali di piattaforma.

Se desiderate modernizzare gradualmente una landscape Delphi esistente o collegare in modo pulito servizi C#, una revisione architetturale con focus su interfacce, dati, operatività e sicurezza è la via più rapida verso decisioni affidabili. Maggiori dettagli in un confronto diretto:

Nell’ambito funzionale rivestono inoltre un ruolo importante la Delphi modernizzazione e le REST-API per il software esistente, quando integrazioni, flussi di dati e ulteriore sviluppo devono operare 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 dall'inizio.

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 rimandati a fasi successive.
  • Vede in anticipo quale percorso è economicamente ed operativamente sostenibile.

Condividi il post

Condividi direttamente questo articolo

LinkedIn, X, XING, Facebook, WhatsApp e e-mail sono immediatamente disponibili. Per Instagram prepariamo direttamente il link e un breve testo.

E-mail

Instagram si apre in una nuova scheda. Il link e il breve testo vengono copiati prima negli appunti.