Från magasinets tema till projektpraxis
Passande tjänste- och tekniksidor för inlägget
I många IT‑avdelningar är utgångsläget likartat: En stabil, processnära Delphi-desktopapplikation bär kritiska processer, samtidigt som nya krav driver mot webb, portaler, mobil användning och integration med molntjänster. Samtidigt är C# etablerat i många företag när det gäller tjänster, webb‑API:er och identitetsintegration. Den centrala frågan är därför inte längre „Delphi eller C#?“, utan: C# och Delphi i en gemensam arkitektur—att kombinera dem så att drift, underhåll, datahantering och säkerhet förblir hanterbara.
Detta inlägg beskriver praktiskt användbara arkitekturprinciper som visat sig fungera i företagsmiljöer där inte allt kan eller bör byggas om. Fokus ligger på tydligt ansvar mellan desktopklient, tjänster, data och gränssnitt – och på hur ni planerar moderniseringssteg med låg risk utan att äventyra löpande processer.
Varför blandade teknologistackar är norm i företag
Växande digitala företagslösningar uppstår sällan från grunden. Delphi-applikationer har ofta utökats över många år, nära verksamhetsprocesserna, med omfattande datalogik och djup kunskap om specialfall. Parallellt har nya krav uppstått: självbetjäningsportaler, automatiserade datautbyten, anslutning av DMS/CRM/ERP, stöd för multitenancy, ökat behov av revisionsspårbarhet eller Single Sign‑on.
C# erbjuder i detta sammanhang ofta fördelar för webb‑ och tjänsteekosystem: ett brett hosting‑spektrum, standardiserad middleware, god integration med identitetsleverantörer och etablerade mönster för webb‑API:er. Delphi förblir däremot stark när det gäller högpresterande Windows‑desktopklienter, långsiktigt underhållna VCL‑applikationer eller specifika multiplattforms‑klienter (t.ex. via FMX).
Blandningen är därför inget ”specialfall”, utan en realistisk respons på investeringsskydd och moderniseringstryck. Avgörande är att den gemensamma driften inte blir en permanent byggarbetsplats.
Arkitekturprincip: tydliga skikt istället för språkgränser
När två språk möts är frestelsen stor att organisera separationen längs teknologin (”Allt Delphi är Legacy, allt C# är nytt”). Tekniskt kan det fungera kortsiktigt, men långsiktigt leder det till friktion: dubbla affärsregler, otydliga ansvarsområden och svårt reproducerbara fel.
I stället har en funktionell uppdelning visat sig fungera väl, ofta implementerad som Layer-3 Architektur: presentation (UI), domän (affärslogik) och infrastruktur (dataåtkomst, externa system). Poängen är mindre läroboksmodellen än den konkreta effekten i vardagen: beslut om data, valideringar och arbetsflöden fattas på ett ställe och exponeras via stabila gränssnitt.
I en blandad arkitektur betyder det i praktiken att Delphi kan fortsätta leverera en UI‑del (eller vissa arbetsflöden), medan C# Services kapslar en funktionell domänskikt – eller tvärtom. Viktigt är att gränssnittet mellan skikten är tekniskt rent och testbart.
C# und Delphi in einer gemeinsamen Architektur: drei bewährte Integrationsmuster
För kopplingen mellan Delphi och C# finns det ingen „enda“ rätt väg. Välgrundade beslut styrs av drift, säkerhetskrav, latens, datavolymer och releasecykler. I praktiken har tre mönster etablerat sig.
1) Serviceorientering över HTTP/REST som standardkoppling
Ofta är en koppling via REST-API:er (HTTP-baserade gränssnitt) mest robust för drift och vidareutveckling. Delphi-klienter anropar C#- eller Delphi-tjänster; C#-portaler använder samma endpunkter. Denna löskoppling gör releaser mer förutsägbara: en klientuppdatering är inte nödvändig om API:t förblir bakåtkompatibelt.
Viktigt är en professionell utformning: timeouts, omförsök, idempotens (upprepningsbara förfrågningar utan sidoeffekter), tydliga felkoder och en versionshanteringsstrategi. För administration och drift räknas dessutom: enhetliga loggar, spårbara request-ID:er och väl mätbara svarstider.
2) Gemensam databas: bara med tydliga spelregler
Gemensam databasåtkomst av Delphi och C# kan verka lockande eftersom det initialt går snabbt. På längre sikt är det dock riskabelt om båda miljöerna skriver direkt till samma tabellbestånd. Anledningen: affärsregler flyttas till triggers, Stored Procedures eller till „någonstans i klienten“. Det försvårar felanalys och revisioner.
Om en gemensam databas är oundviklig (t.ex. i övergångsfasen) hjälper tydliga regler:
- Centralisera skrivåtkomst: ett system är „System of Record“ för vissa entiteter.
- Definiera kontrakt: vyer eller API:er som ett stabilt lässkikt i stället för direkt tabellåtkomst.
- Planera migrationsfönster: rulla alltid ut databasändringar bakåtkompatibelt (t.ex. nya kolumner först som valfria).
Tekniskt är databasen då en infrastrukturkomponent, inte integrationsbussen.
3) Messaging/Events för asynkrona processer
För löskopplade flöden (t.ex. importkörningar, aviseringar, efterbearbetning, gränssnittsjobb) är en asynkron modell lämplig: ett system publicerar händelser, ett annat bearbetar dem. Det minskar direkta beroenden och stabiliserar belastningstoppar.
För IT-ledning och administratörer är följande viktigt: övervakning (kölängder), dead-letter-koncept (misslyckade meddelanden), återstartsbeteende och tydlig funktionell idempotens. Händelser är inget substitut för ordnad stamdatahantering, men ett bra verktyg för robusta processkedjor.
Datakontrakt och kompatibilitet: den underskattade kärnan
Oavsett integrationsmönster avgör kvaliteten på datakontrakten stabiliteten. Ett datakontrakt är den bindande beskrivningen av fält, typer, obligatoriskt/valfritt och semantik. I REST-API:er är detta typiskt JSON; viktigt är inte „JSON i sig“, utan disciplinen i hanteringen av förändringar.
Välkända regler som avsevärt förenklar driften:
- Utöka istället för att bryta: lägg till nya fält, fortsätt att leverera gamla fält initialt.
- Dokumentera fältsemantik: inte bara „string“, utan t.ex. ISO-datum, tidszon, tillåtna tillstånd.
- Behandla enum-värden tolerant: klienter måste klara okända värden (framåtkompatibilitet).
- Använd API-versionering medvetet: inte varje release behöver en ny version; men bakåtinkompatibla ändringar måste vara tydligt kapslade.
Dessa punkter är särskilt viktiga när Delphi-desktopklienter inte kan uppdateras lika ofta som webbtjänster.
Autentisering och auktorisation: en gemensam säkerhetsmodell
Blandade arkitekturer misslyckas sällan på grund av „teknik“, oftare på grund av inkonsekvent säkerhet. För företag är det centralt: vem får göra vad? Hur verifieras det? Hur revideras det? En gemensam modell undviker dubbel användarhantering och motstridiga roller.
I praktiken leder det till ett centralt identitetsskikt: till exempel via SAML 2.0 (federerat single sign-on, vanligt i enterprise-miljöer) eller OpenID Connect (OAuth2-baserat, ofta för moderna webb-API:er). C#-Services låter sig oftast kopplas direkt till en Identity Provider; Delphi-klienter kan hämta tokens och skicka med dem vid API-anrop. Viktigt är att även desktop-applikationer inte får „specialrättigheter“ via databasåtkomst.
Centralt för administratörer:
- Tokenlivslängder och refresh-strategi (så att klienter kör stabilt och ändå är säkra)
- Service-till-service-autentisering för intern kommunikation (t.ex. mTLS eller signerade tokens)
- Principen om minsta privilegium: roller och behörigheter får inte vara för grovt definierade
- Revisionsloggar: säkerhetsrelevanta åtgärder ska kunna spåras i logg
Driftskoncept: Windows- och Linux-tjänster, IIS och processer i det dagliga arbetet
En arkitektur är i företaget endast „bra“ om den är driftbar: uppdateringar kan planeras, fel kan lokaliseras, belastning kan hanteras. I blandade landskap är de vanligaste driftsvarianterna:
- Windows- och Linux-tjänster: lämpliga för bakgrundsjobb, gränssnittskörningar och workerprocesser; väl integrerbara i klassiska Windows-serverdriftsmodeller.
- Windows- och Linux-tjänster/Daemon: rimligt för containeriserade eller VM-baserade driftsmodeller; ofta stabilt i kontinuerlig drift, god automatisering via systemd.
- Microsoft IIS: etablerad hosting för webbapplikationer och reverse-proxy-scenarier i Windows-centrerade miljöer.
Det är viktigt att Delphi- och C#-komponenter uppfyller liknande driftstandarder: konsekventa Health-Endpoints (livstecken), definierade timeouts, begränsad resursförbrukning samt ett tydligt deployment- och rollback-förfarande. Det minskar „teknologispecifika“ specialbehandlingar.
Loggning, tracing och mätvärden: en gemensam observability-nivå
Särskilt vid två teknologistackar är genomgående diagnoskedjor avgörande. Ett typiskt problem: Delphi-klienten rapporterar „Fel vid lagring“, C#-tjänsten har en timeout, databasen rapporterar lås – utan gemensam kontext.
I praktiken har följande visat sig fungera:
- Korrelations-ID per förfrågan (Client → API → DB), så att loggar kan kopplas ihop.
- Strukturerad loggning (nyckel/värde istället för rena textrader), för att kunna filtrera senare.
- Metriker för latens, felkvoter, kölängder och resursanvändning.
- Felklassificering: verksamhetsfel (validering) åtskilt från tekniska fel (timeout, nätverk).
Dessa grundläggande principer sparar i praktiken mer tid än varje diskussion om „det rätta språket“.
Datuåtkomst och migrering: BDE-avveckling, FireDAC och moderna databaser
I Delphi-bestånd spelar dataåtkomst historiskt en stor roll. Där äldre åtkomstvägar som Borland Database Engine (BDE) fortfarande används uppstår ytterligare påfrestningar: operativsystemuppdateringar, övergångar till 64‑bit, drivrutinstillgänglighet och säkerhetskrav. En BDE-avveckling är då inte bara en modernisering utan också en riskreducering.
Typiskt är övergången till en BDE-avveckling med nativen anslutning (modernt åtkomstlager i Delphi), kombinerat med en databas som är operativt hanterbar (t.ex. PostgreSQL, SQL Server, MariaDB). För en gemensam Delphi/C#-arkitektur är två aspekter viktiga:
- Transaktionsgränser: Vem startar/committar transaktionerna, och hur hanteras parallella skrivoperationer?
- Locking- och isolationsstrategi: så att skrivbordsarbetsflöden och tjänster inte blockerar varandra.
Vid migreringar är en stegvis planering fördelaktig: modernisera först drivrutins- och åtkomstskiktet, konsolidera sedan datamodellen, och därefter stabilisera integrationsgränssnitten. På så sätt blir felkällor isolerbara och återställningar realistiska.
Releasehantering: olika uppdateringscykler under ett tak
Ett återkommande spänningsfält är uppdateringsfrekvensen: webbtjänster kan rullas ut oftare, skrivbordsklienter betydligt mer sällan (rollout-fönster, användarkommunikation, paketering). En gemensam arkitektur måste ta hänsyn till denna asymmetri.
Praktiska konsekvenser:
- API-bakåtkompatibilitet är ett krav, inte ett tillval.
- Feature Flags (funktionella flaggor) hjälper till att kontrollerat aktivera nya funktioner på serversidan.
- Schemanmigrationer måste ske i faser: utöka databasen först, låt tjänsten använda den, och uppdatera klienten efteråt.
- Tydlig avveckling: Ta bort gamla endpunkter eller fält först efter en definierad tidsperiod.
Särskilt i reglerade miljöer är det viktigt att dokumentera dessa regler skriftligt som arkitekturriktlinjer, så att beslut inte uppfinns på nytt i varje projekt.
Typiska fallgropar och hur man systematiskt undviker dem
Ur driftsynpunkt är de vanligaste problemen i blandade Delphi/C#-landskap väl förutsägbara. Om man adresserar dem tidigt minskar de långsiktiga kostnaderna märkbart.
Fallgrop 1: dubbel affärslogik
Om Delphi-klient och C#-tjänst implementerar samma regler på olika sätt uppstår „spökfel“: en process fungerar i UI men misslyckas vid API-import. Motmedel: centralisera regler i domänlagret (tjänst) eller tilldela dem tydligt funktionellt, inklusive entydiga valideringssvar.
Fallgrop 2: UI-workarounds istället för rena gränssnitt
Att „snabbt skriva ett databasfält“ kan i enskilda fall verka ofarligt, men skapar skugggränssnitt utan logging, autentisering och versionering. Bättre: gå konsekvent via definierade endpunkter, även om det initialt kräver mer disciplin.
Fallgrop 3: oklara ansvarsområden i driften
Om det inte är tydligt vilket team som ansvarar för vilken tjänst, vilken logg och vilka driftsparametrar, slutar felsökningen i pingpong. Praktiskt hjälpmedel är en servicekarta (vilken tjänst, vilka beroenden, vilka portar, vilka interna SLA:er) och enhetliga runbooks för vanliga störningar.
Fallgrop 4: bristande säkerhetskonsistens
En portal med SSO, men en desktopklient med lokala adminkonton är i många revisioner ett problem. Ett gemensamt identitets- och rollmodell minskar risk och supportarbete.
Beslutsstöd: Vad stannar i Delphi, vad går i C#?
En rimlig uppdelning beror mindre på ideologi än på processnära krav och driftkrav. Som vägledning ur ett arkitektur- och driftperspektiv:
- Delphi är ofta lämpligt för: befintliga Windows-desktopklienter (VCL), mycket responsiva UI-workflows, scenario med nära offline-stöd, långsiktigt underhåll av etablerade gränssnitt.
- C# är ofta lämpligt för: central REST-API:er, integrationsservices mot ERP/DMS/CRM, identitetsnära komponenter, portaler och backendprocesser med hög förändringstakt.
- Medvetet besluta: datalogik och validering bör inte ligga „i klienten“ när flera frontend finns (desktop, portal, importjobb).
Viktigt: Målet är inte att „flytta allt till C#“, utan en hållbar totalarkitektur där moderniseringssteg är planbara och affärsprocesserna kör stabilt.
Moderniseringsväg: Stegvis från applikation till system
I praktiken är en gemensam arkitektur ofta ett övergångsskede, men ett långt sådant. En realistisk moderniseringsväg undviker storskaliga projekt med hög risk och satsar på mätbara delmål:
- Stabilisera gränssnitten: införa REST-API som den funktionella kanten, även om allt internt inte är „fint“ än.
- Modernisera dataåtkomst: BDE-ersättning, drivrutiner, 64‑bit-kapabilitet, tydliga transaktioner.
- Centralisera identitet: SSO och rollmodell för alla åtkomstvägar.
- Enhetliggör drift: Logging/monitoring/health, tydliga deployment-processer, reproducerbara miljöer.
- Lösgör fackliga moduler: flytta särskilt ändringstunga delar till services, gör UI stegvis mindre tung.
Denna ordning är inte dogmatisk, men den minimerar i regel beroenden: utan stabila gränssnitt och ett driftkoncept blir varje vidare förändring dyrare.
Slutsats: Integration är en arkitekturfråga, inte en språkfråga
En hållbar kombination av Delphi och C# uppstår inte genom „brobibliotek“, utan genom klara funktionella kanter, rena datakontrakt och ett driftkoncept som tar monitoring, säkerhet och release-hantering på allvar. När C# och Delphi i en gemensam arkitektur medvetet samspelar utifrån ansvar, vinner företag framför allt en sak: modernisering utan processbrott. Delphi kan fortsatt bära stabila desktop-workflows pålitligt, medan C#-tjänster tillhandahåller integration, webb-API:er och portaler som centrala plattformsfunktioner.
Om ni vill modernisera en befintlig Delphi-miljö stegvis eller ansluta C#-tjänster på ett rent sätt, är en arkitekturöversyn med fokus på gränssnitt, data, drift och säkerhet det snabbaste sättet till välgrundade beslut. Mer om detta i direkt dialog:
I det verksamhetsmässiga sammanhanget spelar även Delphi Modernisering och REST-API för befintlig programvara en viktig roll när integrationer, dataflöden och vidareutveckling måste samverka på ett konsekvent och förutsägbart sätt.
Nästa steg
När ett ämne blir ett verkligt projekt bör arkitektur, befintliga system och drift behandlas gemensamt redan i ett tidigt skede.
Vi stöder inte bara vid enstaka frågor, utan även när kodsfragment, legacy-frågor eller portalidéer ska utvecklas till ett robust företagsprojekt.
- Nuläge, målbild och tekniska risker bedöms tillsammans.
- REST, dataåtkomst, portaler och utrullning skjuts inte upp som sena följder.
- Ni ser tidigt vilken väg som är ekonomiskt och driftsmässigt bärkraftig.