Fra magasinets tema til projektpraksis
Passende service- og tekniske sider til artiklen
I mange IT-afdelinger er udgangssituationen lignende: En stabil, procesnær Delphi-desktopapplikation bærer kritiske processer, mens nye krav presser i retning af web, portaler, mobil brug og integration med cloud-tjenester. Samtidig er C# i mange virksomheder etableret, når det gælder services, Web-APIs og Identity-Integration. Det centrale spørgsmål er derfor ikke længere „Delphi eller C#?“, men: C# und Delphi in einer gemeinsamen Architektur så de kombineres, så drift, vedligehold, datalagring og sikkerhed forbliver håndterbare.
Dette indlæg beskriver praksisegnede arkitekturprincipper, der har vist sig i virksomhedsmiljøer, hvor ikke alt kan eller bør bygges om. Fokus ligger på klare ansvarsområder mellem desktop-klient, services, data og grænseflader – og på, hvordan du planlægger moderniseringstrin med lav risiko uden at bringe de igangværende processer i fare.
Warum gemischte Stacks in Unternehmen normal sind
Voksede digitale virksomhedsløsninger opstår sjældent på en grøn mark. Delphi-applikationer er ofte blevet udvidet over mange år, tæt på forretningsprocesserne, med omfattende datalogik og dyb viden om særlige tilfælde. Parallelt er der opstået nye krav: Self-Service-Portale, automatiserede dataudvekslinger, tilslutning af DMS/CRM/ERP, mandantforvaltning, øget auditability eller Single Sign-on.
C# tilbyder i denne sammenhæng ofte fordele for web- og service-økosystemer: bredt hosting-spektrum, standardiseret middleware, god integration med Identity Provider og etablerede patterns for Web-APIs. Delphi er derimod stærk, når det gælder performante Windows-desktopklienter, langsigtet vedligeholdte VCL-applikationer eller specifikke multiplatform-klienter (f.eks. via FMX).
Blandingen er derfor ikke et „Sonderfall“, men et realistisk svar på investeringsbeskyttelse og moderniseringstryk. Det afgørende er, at den fælles drift ikke bliver et permanent byggeprojekt.
Architekturgrundsatz: klare Schichten statt Sprachgrenzen
Når to sprog mødes, er fristelsen stor til at organisere adskillelsen langs teknologien („Alles Delphi ist Legacy, alles C# ist neu“). Teknisk virker det ofte på kort sigt, men på længere sigt fører det til friktion: dobbelte forretningsregler, uklare ansvarsfordelinger og vanskeligt reproducerbare fejl.
I stedet har en faglig lagdeling vist sig at virke, ofte realiseret som Layer-3 Architektur: præsentation (UI), domæne (forretningslogik) og infrastruktur (dataadgang, eksterne systemer). Pointen er mindre lærebogsmodellen end den konkrete effekt i hverdagen: beslutninger om data, valideringer og workflows træffes ét sted og stilles til rådighed via stabile grænseflader.
I en blandet arkitektur betyder det i praksis: Delphi kan fortsat levere en UI-del (eller bestemte workflows), mens C# Services indkapsler et fagligt domænelag – eller omvendt. Det vigtige er, at kanten mellem lagene er teknisk ren og testbar.
C# und Delphi in einer gemeinsamen Architektur: drei bewährte Integrationsmuster
For koblingen af Delphi og C# findes der ikke „én“ rigtig vej. Gode beslutninger tager udgangspunkt i drift, sikkerhedskrav, latens, datavolumen og release-cyklusser. I praksis har tre mønstre gjort sig gældende.
1) Service-Orientierung über HTTP/REST als Standardkopplung
Ofte er den mest robuste løsning for drift og videreudvikling en kobling via REST-API’er (HTTP-baserede grænseflader). Delphi-klienter kalder C#- eller Delphi-services; C#-portaler bruger de samme endepunkter. Denne entkobling gør releases mere planlagte: en klientopdatering er ikke nødvendigvis nødvendig, hvis API’en forbliver bagudkompatibel.
Vigtigt er en professionel udformning: timeouts, retries, idempotens (gentagelige forespørgsler uden sideeffekter), klare fejlkoder og en versionsstrategi. For administration og drift tæller desuden: ensartede logs, sporbare request-ID’er og veldokumenterede, målbare svartider.
2) Gemeinsame Datenbank: nur mit klaren Spielregeln
En fælles databaseadgang for Delphi og C# virker tillokkende, fordi den i starten er hurtig. På lang sigt er den dog risikofyldt, hvis begge parter skriver direkte til den samme tabelmængde. Årsagen er, at forretningsregler forskydes ind i triggers, stored procedures eller ‚et eller andet sted i klienten‘. Det gør fejlsøgning og audits vanskeligere.
Hvis en fælles database er uundgåelig (fx i overgangsperioder), hjælper klare regler:
- Schreibzugriffe zentralisieren: ét system er ‚System of Record‘ for bestemte entiteter.
- Verträge definieren: views eller APIs som et stabilt læselag i stedet for direkte tabeladgang.
- Migrationsfenster planen: databaseændringer udrulles altid bagudkompatibelt (fx nye kolonner gøres først valgfrie).
Teknisk er databasen dermed en infrastrukturkomponent, ikke integrationsbussen.
3) Messaging/Events für asynchrone Prozesse
For entkoblede forløb (fx importkørsler, notifikationer, efterbehandling, interface-jobs) er en asynkron model formålstjenlig: ét system publicerer hændelser, et andet behandler dem. Det reducerer direkte afhængigheder og stabiliserer belastningstoppe.
For IT-ledelse og administratorer er følgende væsentligt: overvågning (kø-længder), dead-letter-koncepter (fejlede beskeder), genstartadfærd og klar faglig idempotens. Events er ikke en erstatning for ordentlig masterdatahåndtering, men et nyttigt værktøj til robuste proceskæder.
Datenverträge und Kompatibilität: der unterschätzte Kern
Uafhængigt af integrationsmønsteret afgør kvaliteten af datakontrakterne stabiliteten. En datakontrakt er den bindende beskrivelse af felter, typer, obligatorisk/valgfrit og semantik. I REST-API’er er dette typisk JSON; vigtigt er ikke ‚JSON i sig selv‘, men disciplinen i håndteringen af ændringer.
Prøvede regler, der mærkbart forenkler driften:
- Erweitern statt brechen: tilføj nye felter, fortsæt indtil videre med at levere de eksisterende felter.
- Feldsemantik dokumentieren: ikke kun ’string‘, men fx ISO-dato, tidszone, tilladte tilstande.
- Enum-Werte tolerant behandeln: klienter skal kunne håndtere ukendte værdier (fremadkompatibilitet).
- API-Versionierung bewusst einsetzen: ikke hvert release behøver en ny version; men breaking changes skal være tydeligt kapslet ind.
Disse punkter er særligt vigtige, når Delphi-desktop-klienter ikke kan opdateres så hyppigt som webservices.
Autentificering og autorisation: en fælles sikkerhedsmodel
Blandede arkitekturer fejler sjældent på „teknik“, oftere på inkonsistent sikkerhed. For virksomheder er det afgørende: Hvem må hvad? Hvordan kontrolleres det? Hvordan auditeres det? En fælles model undgår dobbelt brugeradministration og modstridende roller.
I praksis fører det til et centralt identitetslag: for eksempel via SAML 2.0 (fødereret Single Sign-on, ofte i enterprise-miljøer) eller OpenID Connect (OAuth2-baseret, ofte for moderne Web-APIs). C#-Services kan som regel kobles direkte til en Identity Provider; Delphi-klienter kan hente adgangstokens og sende dem med ved API-kald. Det er vigtigt, at også desktop-applikationer ikke får „særrettigheder“ via direkte databaseadgang.
Centralt for administratorer:
- Token-levetider og refresh-strategi (så klienter kører stabilt og samtidig er sikre)
- Service-til-service-autentificering for intern kommunikation (f.eks. mTLS eller signerede tokens)
- Least Privilege: roller og rettigheder må ikke være for groft afgrænsede
- Audit-Logs: logge sikkerhedsrelevante handlinger, så de kan efterprøves
Driftskoncepter: Windows- und Linux-Services, IIS und Prozesse im Alltag
En arkitektur er kun i virksomheden „god“, hvis den er driftbar: opdateringer kan planlægges, fejl kan lokaliseres, belastning kan håndteres. I blandede landskaber er de hyppigste driftsvarianter:
- Windows- und Linux-Services: egnet til baggrundsjob, integrationskørsler og workere; nemt at integrere i klassiske Windows-serverdriftsmodeller.
- Windows- und Linux-Services/Daemon: fornuftigt for containeriserede eller VM-baserede driftsmodeller; ofte stabil i kontinuerlig drift, god automatisering via systemd.
- Microsoft IIS: etableret hosting for webapplikationer og reverse-proxy-scenarier i Windows-centrerede miljøer.
Det er vigtigt, at Delphi- og C#-komponenter lever op til lignende driftsstandarder: konsistente Health-Endpoints (livstegn), definerede timeouts, begrænset ressourceforbrug samt en klar Deployment- og Rollback-procedure. Det reducerer „teknologispecifikke“ særbehandlinger.
Logging, Tracing und Metriken: ein gemeinsames Observability-Niveau
I praksis har følgende vist sig effektive:
- Korrelations-IDs per request (Client → API → DB), så logs kan samles.
- Struktureret Logging (nøgle/værdi i stedet for rene tekstlinjer), for at kunne filtrere senere.
- Metrikker for latenstid, fejlrate, kølængder og ressourceforbrug.
- Fejlklassifikation: forretningsfejl (validering) adskilt fra tekniske fejl (Timeout, Netzwerk).
Disse grundprincipper sparer i praksis mere tid end enhver diskussion om „det rigtige sprog“.
Dataadgang og migration: BDE-udskiftning, FireDAC og moderne databaser
I Delphi-bestandene spiller dataadgang historisk en stor rolle. Hvor ældre adgangsveje som Borland Database Engine (BDE) stadig er i brug, opstår der ekstra pres: styresystemopdateringer, 64-bit-overgange, driver-tilgængelighed, sikkerhedskrav. En BDE-udskiftning er i sådanne tilfælde ikke blot modernisering, men risikoreduktion.
Typisk er overgangen til en BDE-udskiftning med native tilslutning (moderne dataadgangslag i Delphi), kombineret med en database, der er operationelt håndterbar (f.eks. PostgreSQL, SQL Server, MariaDB). For en fælles Delphi/C#-arkitektur er to aspekter vigtige:
- Transaktionsgrænser: Hvem starter/committerer transaktioner, og hvordan reguleres parallelle skriveadgange?
- Locking- og isolationsstrategi: så desktop-arbejdsgange og services ikke blokerer hinanden.
Ved migrationer anbefales en trinvist plan: først modernisere driver- og adgangslaget, så konsolidere datamodellen, og efterfølgende stabilisere integrationsgrænsefladerne. På den måde bliver fejlårsager isolerbare, og rollbacks realistiske.
Releasestyring: forskellige opdateringscyklusser forenes
Et tilbagevendende spændingsfelt er opdateringsfrekvensen: webservices kan rulles oftere ud, desktop-klienter ofte sjældnere (rollout-vinduer, brugerkommunikation, pakning). En fælles arkitektur må tage denne asymmetri i betragtning.
Praktiske konsekvenser:
- API-bagudkompatibilitet er et krav, ikke et tilvalg.
- Feature Flags (funktionelle kontroller) hjælper med at aktivere nye funktioner kontrolleret på serversiden.
- Skema-migrationer må køre i faser: først udvide databasen, derefter lade servicen bruge de nye strukturer, og til sidst opdatere klienten.
- Klar udfasning: gamle endepunkter eller felter fjernes kun efter en defineret periode.
Typiske faldgruber og hvordan man systematisk undgår dem
Set fra driftsvinklen er de hyppigste problemer i blandede Delphi/C#-landskaber vel forudsigelige. Hvis man adresserer dem tidligt, falder de langsigtede omkostninger mærkbart.
Faldgrube 1: dobbelt forretningslogik
Hvis Delphi-clienten og C#-servicen implementerer de samme regler forskelligt, opstår „spøgelsesfejl“: en proces fungerer i UI, men fejler ved API-import. Modmiddel: centralisere reglerne i domænelaget (service) eller tildele dem klart fagligt, inklusive entydige valideringssvar.
Faldgrube 2: UI-omgåelser i stedet for rene grænseflader
»Lige at skrive et databasefelt hurtigt« virker i det enkelte tilfælde harmløst, men skaber skyggegrænseflader uden logging, autentificering og versionering. Bedre: konsekvent gå via definerede endepunkter, selvom det i starten kræver mere disciplin.
Faldgrube 3: uklare ansvarsfordelinger i driften
Hvis det ikke er klart, hvilket team der er ansvarligt for hvilken service, hvilket log og hvilke driftsparametre, ender fejlsøgning i ping-pong. Praktisk hjælper et servicelandkort (hvilken tjeneste, hvilke afhængigheder, hvilke porte, hvilke interne SLA’er) og ensartede runbooks til hyppige fejltilfælde.
Faldgrube 4: manglende sikkerhedskonsistens
Et portal med SSO, men en desktop-klient med lokale admin-konti er i mange audits et problem. En fælles identity- og rollemodel reducerer risiko og supportarbejde.
Beslutningshjælp: Hvad forbliver i Delphi, hvad går til C#?
Den fornuftige opdeling afhænger mindre af ideologi end af procesnærhed og driftskrav. Som retningslinje fra et arkitektur- og driftsperspektiv:
- Delphi er ofte godt til: eksisterende Windows-desktop-klienter (VCL), meget reaktionshurtige UI-workflows, offline-nære scenarier, langsigtet vedligehold af voksede brugerflader.
- C# er ofte godt til: centrale REST-API’er, integrationsservices til ERP/DMS/CRM, identity-nære komponenter, portaler og backend-processer med høj ændringsfrekvens.
- Bevidst vælge: Datalogik og validering bør ikke være „i klienten“, når flere frontends eksisterer (Desktop, Portal, Importjobs).
Vigtigt: Målet er ikke „alt til C#“, men en robust samlet arkitektur, hvor moderniseringstrin kan planlægges, og virksomhedens processer kører stabilt.
Moderniseringssti: Trinvis fra applikation til system
I praksis er en fælles arkitektur ofte en overgang, men en langvarig én. En realistisk moderniseringssti undgår store projekter med høj risiko og satser på målbare delmål:
- Stabilisere grænseflader: Indfør REST-API’en som en faglig kant, selvom ikke alt internt er „pænt“ endnu.
- Modernisere dataadgang: BDE-udskiftning, drivere, 64‑bit-understøttelse, klare transaktioner.
- Centralisere identitet: SSO og rollemodel for alle adgangsveje.
- Uniformere driften: Logging/Monitoring/Health, klare Deployments, reproducerbare miljøer.
- Adskil faglige moduler: Flyt særligt ændringsintensive dele til services, og slank UI’en trinvis.
Denne rækkefølge er ikke dogmatisk, men den mindsker typisk afhængigheder: Uden stabile grænseflader og et driftkoncept bliver enhver yderligere ændring dyrere.
Konklusion: Integration er en arkitekturopgave, ikke et sprogspørgsmål
En bæredygtig kombination af Delphi og C# opstår ikke gennem „Brückenbibliotheken“, men gennem klare faglige kanter, rene datakontrakter og et driftkoncept, der tager Monitoring, Security og Release-Management alvorligt. Når C# og Delphi i en fælles arkitektur bevidst spiller sammen langs ansvarsområder, opnår virksomheder især ét: modernisering uden procesbrud. Delphi kan fortsat bære stabile desktop-workflows pålideligt, mens C#-services leverer integration, Web-APIs og portaler som centrale platformfunktioner.
Hvis I ønsker at modernisere en eksisterende Delphi-landskab trinvis eller tilkoble C#-services korrekt, er et arkitektur-review med fokus på grænseflader, data, drift og sikkerhed den hurtigste vej til holdbare beslutninger. Mere om det i direkte dialog:
I det faglige miljø spiller både Delphi Modernisierung og REST-API for eksisterende software en vigtig rolle, når integrationer, dataflows og videreudvikling skal fungere problemfrit sammen.
Næste trin
Når et emne bliver til et reelt projekt, bør arkitektur, eksisterende systemer og drift tidligt vurderes samlet.
Vi støtter ikke kun ved enkeltspørsmål, men også når kildekodeudsnit, legacy-komponenter eller portalidéer skal udvikles til et robust virksomhedsprojekt.
- Eksisterende tilstand, målbillede og tekniske risici vurderes samlet.
- REST, dataadgang, portaler og idrulning bliver ikke udskudt som eftertanker.
- I ser tidligt, hvilken vej der er økonomisk og driftsmæssigt holdbar.