Migrazione WCF a CoreWCF: costi, metodo e rischi
Matteo Migliore

Matteo Migliore è un imprenditore e architetto software con oltre 27 anni di esperienza nello sviluppo di soluzioni basate su .NET e nell'evoluzione di architetture applicative per imprese e organizzazioni di alto profilo.

Ha guidato progetti enterprise, formato centinaia di sviluppatori e aiutato aziende di ogni dimensione a semplificare la complessità trasformando il software in guadagni per il business.

Migrazione WCF a CoreWCF: costi, metodo e rischi

Il responsabile IT di un'azienda di logistica in provincia di Verona mi chiama per un'altra cosa: vuole aggiornare il server su cui gira il gestionale di magazzino. Gli chiedo dove vive il codice che parla con i palmari, con il portale dei clienti e con il software del corriere. Mi risponde, con un tono che conosco bene, che c'è "un servizio" fatto nel 2011 da un consulente che non c'è più. Si chiama OrdiniService.svc, gira su un Windows Server 2012 e ha quattordici programmi collegati. Nessuno ha il progetto aperto da tre anni. Tutti lo usano ogni minuto.

Questa guida è per chi ha un servizio così e deve decidere cosa farne. Ti spiego come capire se serve davvero migrarlo, quali strade esistono, quanto costa ciascuna e dove si rompe di solito il lavoro. La migrazione da WCF a CoreWCF è la strada più economica quando i client collegati non si possono toccare: si tiene lo stesso contratto SOAP, si sposta il server su .NET 10 e si lasciano immutati tutti i programmi che lo chiamano, per circa 12.000-30.000 euro e quattro-otto settimane di lavoro per un servizio di medie dimensioni.

Se prima di tutto vuoi capire il quadro dell'intero applicativo, parti da migrazione da .NET Framework a .NET 10. Qui parliamo solo dei servizi WCF, che hanno problemi tutti loro.

Perché WCF è il pezzo più pericoloso del tuo software legacy

WCF su .NET Framework funziona ancora e continuerà a ricevere correzioni finché c'è Windows che lo ospita, ma Microsoft non lo porta su .NET moderno: la parte server non esiste in .NET 10, quindi ogni giorno senza un piano aumenta il costo di uscita. Il rischio non è che smetta di funzionare domani. Il rischio è che nessuno sappia più come si tocca quando serve toccarlo.

Windows Communication Foundation è nato nel 2006, insieme a .NET Framework 3.0, per un'epoca in cui i servizi si scambiavano messaggi SOAP, i contratti si descrivevano in un file WSDL e la sicurezza era una questione di certificati e protocolli WS-*. Funzionava bene. Per quindici anni è stato il modo standard di far parlare fra loro applicazioni aziendali .NET, e ha lasciato dietro di sé migliaia di servizi in produzione, spesso invisibili.

La parte client è stata portata su .NET moderno: i pacchetti System.ServiceModel permettono a un'applicazione nuova di chiamare un servizio WCF esistente. La parte server no. Quando Microsoft ha deciso di non portare il server, ha anche indicato due alternative: gRPC per chi vuole un protocollo moderno e REST con ASP.NET Core per chi vuole un'interfaccia web. Per chi non poteva riscrivere tutti i client, la comunità ha costruito CoreWCF, un progetto aperto del .NET Foundation, sostenuto con contributi di Microsoft e di Amazon, che riporta il modello WCF su ASP.NET Core.

I tre costi nascosti di un servizio che non si migra

Il primo costo è il sistema operativo. WCF server dipende da .NET Framework 4.8, e .NET Framework 4.8 vive finché vive il Windows su cui gira. Il giorno in cui devi lasciare Windows Server 2012 o 2016, il servizio resta indietro con tutto il resto. Il secondo costo è la sicurezza: i protocolli e le librerie non ricevono più evoluzioni, e le richieste di audit, sempre più frequenti, chiedono conto di componenti fermi da anni. Il terzo costo è la conoscenza: chi sa configurare un binding WS-Federation a memoria va in pensione, e i giovani sviluppatori non l'hanno mai visto.

Quando non serve migrare subito

Se il servizio ha un solo client, se quel client è sotto il tuo controllo e se tutto gira in una rete interna senza esposizione, il rischio è basso e puoi rimandare. Succede più di quanto si pensi: un servizio che serve due programmi interni di un reparto non è un'emergenza. Lo diventa quando qualcuno fuori dall'azienda lo chiama, perché lì non decidi tu quando cambiare.

Il segnale che conta è la risposta a una domanda semplice: se domani il server si rompe, in quanto tempo lo ricostruisci? Se la risposta è "non so, c'è un backup della macchina", hai un problema di continuità, non di tecnologia. Lo risolvi con una migrazione, e la scelta fra le strade che seguono dipende da quanti client hai e da chi li controlla.

Quali strade esistono: CoreWCF, gRPC, REST o riscrittura

Le strade sono quattro: tenere WCF dov'è, spostarlo su CoreWCF mantenendo il contratto SOAP, sostituirlo con gRPC o con un'API REST, oppure riscrivere tutto. La scelta dipende da una sola cosa: puoi modificare i programmi che chiamano il servizio, oppure no?

Ho visto scegliere la strada giusta per la ragione sbagliata, e quella sbagliata per ragioni di moda. Un'azienda ha riscritto in REST un servizio con undici client, di cui tre non più modificabili perché il fornitore era sparito, e ha passato sei mesi a ricostruire adattatori. Un'altra ha lasciato un servizio su CoreWCF con un solo client interno, quando in tre settimane avrebbe potuto passare a una API semplice e non portarsi dietro SOAP per altri dieci anni.

StradaCosto tipicoQuando convieneLimite principale
Restare su .NET FrameworkQuasi zeroUn client interno, nessuna esposizione, rete chiusaDipendenza da Windows e da .NET 4.8
CoreWCF, stesso contratto12.000-30.000 euroClient che non puoi o non vuoi toccarePorti con te SOAP e il suo modello
API REST con ASP.NET Core20.000-60.000 euro, più i clientPochi client sotto il tuo controllo, apertura al webTocchi ogni programma collegato
gRPC25.000-70.000 euro, più i clientComunicazione fra servizi interni, prestazioni alteNon funziona direttamente dai browser
Riscrittura completa60.000-200.000 euroIl servizio ha logica che comunque va rifattaRischio alto, tempi lunghi

I costi sono ordini di grandezza calcolati a 600 euro al giorno su servizi con venti-quaranta operazioni, e valgono per la parte server. Le colonne dei client sono quelle che fanno saltare i preventivi: ogni programma da adattare è un progetto a sé.

La domanda che decide tutto: chi controlla i client?

Fai una lista di chi chiama il servizio. Per ciascuno scrivi se hai il codice sorgente, se c'è qualcuno che sa modificarlo e se puoi imporre una data per l'aggiornamento. Se anche uno solo è un software di terzi, come quello di un corriere, di una banca o di un cliente, la strada con client invariati diventa quasi obbligata: nessuno ti riscrive il proprio programma per farti un piacere.

Perché non conviene decidere in una riunione

La scelta si fa con i dati. Per una settimana si registra chi chiama quali operazioni, con quale frequenza e da quale indirizzo. Spesso si scopre che metà delle operazioni non viene chiamata da nessuno da anni, e che due client sono in realtà lo stesso programma installato in due sedi. Ridurre il perimetro prima di migrare è la mossa che abbassa di più il costo, e non richiede una riga di codice nuovo.

Il principio di fondo è quello che spiego in riscrivere o rifattorizzare il software: quasi mai si butta tutto, quasi sempre si salva ciò che il resto del mondo già conosce. Qui ciò che il mondo conosce è il contratto.

Come si fa l'inventario del servizio prima di toccare il codice

L'inventario di un servizio WCF risponde a quattro domande: quali operazioni espone, chi le chiama, come si autentica chi le chiama e quali parti del web.config contano davvero. Si fa in tre-cinque giorni e vale da solo metà del preventivo. Chi salta questo passo scopre i problemi a metà lavoro, quando costano il triplo.

Il punto di partenza è il file di configurazione. In un servizio WCF vecchio il web.config contiene tutto: indirizzi, binding, comportamenti, certificati, limiti di dimensione dei messaggi. Quel file è il documento più onesto che hai, perché dice come il servizio funziona davvero e non come lo ricorda qualcuno. Lo leggi riga per riga e ne ricavi un foglio con una voce per ogni binding e ogni endpoint.

Le operazioni: quante, e quante vive

Il contratto elenca le operazioni. I log di IIS, se conservati, dicono quali vengono chiamate. Prendi sette giorni di log, conta le richieste per operazione e dividi in tre gruppi: vive (chiamate ogni giorno), dormienti (chiamate un paio di volte al mese) e morte (zero chiamate). Nel servizio veronese, su 38 operazioni, 21 erano vive, 9 dormienti e 8 mai chiamate. Le otto morte sono sparite dal perimetro senza polemiche.

I client: l'elenco che nessuno ha

Nei log compare l'indirizzo di chi chiama. Con l'indirizzo e due telefonate costruisci la tabella dei client: nome del programma, chi lo mantiene, se esiste il sorgente, se parla SOAP 1.1 o 1.2, se manda un'autenticazione particolare. Nel caso veronese i quattordici client erano in realtà nove programmi, tra cui un vecchio eseguibile Delphi installato in tre depositi, che nessuno sapeva ricompilare. Quel dettaglio ha chiuso la discussione: il contratto non si poteva cambiare di una virgola.

Sicurezza e trasporto: la parte che si dimentica

Ogni servizio WCF ha una modalità di sicurezza: nessuna, trasporto con HTTPS, messaggio firmato, autenticazione Windows, certificato del client. È il punto in cui le migrazioni deragliano, perché ciò che sul vecchio server era "gratis" (l'identità Windows passata dal dominio) su un server nuovo va riconfigurato con cura. Scrivi per ogni client il tipo di credenziale e, quando possibile, ottieni da loro una chiamata di esempio registrata.

Quelle chiamate di esempio, con richiesta e risposta intere, sono l'oro dell'inventario. Servono dopo per verificare che il servizio nuovo risponda come il vecchio. Ne raccogli almeno tre per ogni operazione viva, comprese quelle che finiscono in errore.

Albero di decisione per migrare un servizio WCF: client modificabili o no, rete interna o esposta, CoreWCF, REST o gRPC

Il diagramma riassume il ragionamento: tutto parte dalla possibilità di toccare i client. Se non puoi, vai su CoreWCF. Se puoi e il servizio resta fra sistemi interni, valuti gRPC. Se devi aprirlo a terzi o al web, vai su REST.

CoreWCF in pratica: cosa cambia e cosa resta uguale

CoreWCF riproduce il modello di WCF su ASP.NET Core: contratti, attributi e binding sono gli stessi, cambia il modo di ospitare il servizio, che passa dal file .svc e dal web.config a codice nel Program.cs. Per chi conosce WCF la curva di apprendimento è di giorni, e questo è il motivo per cui costa poco.

Un contratto WCF tipico è un'interfaccia con due attributi. Su CoreWCF resta quasi identico: cambia lo spazio dei nomi degli attributi, da System.ServiceModel a CoreWCF, e il resto del codice di business non si tocca. Il servizio sotto, scritto in forma minima, è tutto quello che serve per far partire un endpoint SOAP su .NET 10:

using CoreWCF;
using CoreWCF.Configuration;
using CoreWCF.Description;

[ServiceContract(Namespace = "http://azienda.example/ordini")]
public interface IOrdiniService
{
    [OperationContract]
    Task<OrdineDto> LeggiOrdineAsync(int id);
}

[DataContract(Namespace = "http://azienda.example/ordini")]
public sealed class OrdineDto
{
    [DataMember(Order = 1)] public int Id { get; set; }
    [DataMember(Order = 2)] public string Cliente { get; set; } = "";
    [DataMember(Order = 3)] public decimal Totale { get; set; }
}

public sealed class OrdiniService : IOrdiniService
{
    public Task<OrdineDto> LeggiOrdineAsync(int id) =>
        Task.FromResult(new OrdineDto { Id = id, Cliente = "Esempio Srl", Totale = 1250.00m });
}

public static class Program
{
    public static void Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);
        builder.Services.AddServiceModelServices();
        builder.Services.AddServiceModelMetadata();
        builder.Services.AddSingleton<IServiceBehavior, UseRequestHeadersForMetadataAddressBehavior>();

        var app = builder.Build();
        app.UseServiceModel(serviceBuilder =>
        {
            serviceBuilder.AddService<OrdiniService>();
            serviceBuilder.AddServiceEndpoint<OrdiniService, IOrdiniService>(
                new BasicHttpBinding(), "/Ordini.svc");

            var metadata = app.Services.GetRequiredService<ServiceMetadataBehavior>();
            metadata.HttpGetEnabled = true;
        });

        app.Run();
    }
}

Due dettagli contano più del resto. Il primo è il Namespace, presente sia sul contratto sia sui dati: è ciò che finisce nei messaggi SOAP, e se cambia di una lettera i client esistenti smettono di capire le risposte. Il secondo è l'Order sui membri dei dati: l'ordine dei campi nel messaggio è parte del contratto, e il serializzatore lo rispetta alla lettera. Dimenticare questi due dettagli è l'errore più frequente, e produce un servizio che "funziona" sul tuo computer e rompe tutti i client in produzione.

Cosa resta identico

Il contratto, i tipi dei dati, la logica di business dentro le operazioni, il WSDL pubblicato e il comportamento visto da fuori. I tuoi client non devono sapere che dall'altra parte c'è un server diverso. È un'idea semplice e per questo potente: l'interno cambia, la porta d'ingresso resta quella.

Cosa cambia davvero

Cambiano il modo di ospitare (niente IIS obbligatorio, il servizio gira su Kestrel o dietro un proxy), la configurazione (da XML a codice e a file di impostazioni), l'inserimento delle dipendenze (ora nativo e coerente col resto di ASP.NET Core, come spiego in dependency injection in C#) e l'accesso ai dati, che spesso era legato a Entity Framework 6 e va portato con il lavoro descritto in migrazione da Entity Framework 6 a EF Core.

Cosa non c'è e come aggirarlo

CoreWCF copre i binding più usati: BasicHttp, WSHttp in forma parziale, NetTcp, e l'accesso web per il formato REST. Non copre tutto. Mancano, o sono limitati, le transazioni distribuite fra servizi (WS-AtomicTransaction), l'affidabilità del messaggio (WS-ReliableMessaging) e alcuni binding duplex. Se il tuo servizio li usa, e pochi lo fanno, la strada è riprogettare quel punto con un meccanismo più moderno, come una coda di messaggi e un'operazione idempotente. Ne parlo più avanti, nella sezione sugli errori.

La migrazione passo per passo: il metodo che uso per ridurre il rischio

Il metodo che riduce il rischio è affiancare il vecchio e il nuovo server per alcune settimane, far passare lo stesso traffico da entrambi e spostare i client uno alla volta, senza spegnere nulla finché i risultati non coincidono. È l'applicazione al caso dei servizi dell'approccio spiegato in strangler fig pattern: il nuovo cresce intorno al vecchio e lo sostituisce senza interruzioni.

Il lavoro si divide in sei passi. Non sono sempre nello stesso ordine, ma in questa sequenza ho ridotto al minimo i fine settimana passati a rimettere a posto le cose.

Passo 1: congelare il vecchio servizio

Per le settimane del progetto non si aggiunge una sola funzione al servizio esistente. Se qualcuno chiede una modifica urgente, la si fa sulle due versioni o la si rimanda. Un bersaglio che si muove rende impossibile confrontare i risultati, e questa è la regola più impopolare e più utile del progetto.

Passo 2: portare la libreria della logica

Quasi sempre dentro il servizio WCF c'è codice di business mischiato con codice di trasporto. Si estrae la logica in una libreria .NET Standard 2.0 o direttamente in .NET 10, con un contratto interno pulito, e il servizio vecchio la richiama. A questo punto il servizio vecchio funziona ancora, ma la parte importante è già dove servirà. Per i casi con molto codice poco documentato, uso un assistente di intelligenza artificiale per descrivere i metodi e proporre i test, nel modo che racconto in refactoring di codice legacy con l'AI.

Passo 3: scrivere i test sulle chiamate registrate

Le chiamate di esempio raccolte nell'inventario diventano test. Si manda la richiesta registrata a un servizio e si confronta la risposta con quella attesa. Il test sotto lo fa in modo semplice: manda lo stesso messaggio SOAP a vecchio e nuovo indirizzo e confronta le due risposte normalizzate, ignorando i campi che per natura cambiano, come data e ora.

using System.Text;
using System.Text.RegularExpressions;

public sealed class ConfrontoServizi
{
    private readonly HttpClient _http = new();

    public async Task<bool> RispondonoUgualiAsync(string urlVecchio, string urlNuovo, string soapAction, string busta)
    {
        var vecchia = await InviaAsync(urlVecchio, soapAction, busta);
        var nuova = await InviaAsync(urlNuovo, soapAction, busta);
        return Normalizza(vecchia) == Normalizza(nuova);
    }

    private async Task<string> InviaAsync(string url, string soapAction, string busta)
    {
        using var richiesta = new HttpRequestMessage(HttpMethod.Post, url)
        {
            Content = new StringContent(busta, Encoding.UTF8, "text/xml")
        };
        richiesta.Headers.Add("SOAPAction", soapAction);
        using var risposta = await _http.SendAsync(richiesta);
        return await risposta.Content.ReadAsStringAsync();
    }

    // Toglie spazi inutili e valori che cambiano a ogni chiamata (date e identificativi di messaggio).
    private static string Normalizza(string xml)
    {
        var senzaSpazi = Regex.Replace(xml, @">\s+<", "><");
        return Regex.Replace(senzaSpazi, @"<(Timestamp|MessageId)>.*?</\1>", "", RegexOptions.Singleline);
    }
}

Non è un test elegante, è un test utile. Ogni differenza che emerge è un'informazione: un campo che il vecchio servizio restituiva nullo e il nuovo vuoto, una data in un formato diverso, un decimale con la virgola al posto del punto. Sono le differenze che i client del 2011 notano subito, e che nessuna revisione del codice scopre.

Passo 4: costruire il servizio nuovo accanto al vecchio

Con la logica in libreria e i test pronti, il nuovo servizio CoreWCF si scrive in pochi giorni. Si pubblica su un indirizzo diverso, sullo stesso server o su uno nuovo, e si lancia la batteria di confronto. Il lavoro vero è far diventare verdi tutti i test, uno dopo l'altro, e ogni test rosso è una domanda su come il vecchio sistema si comportava davvero.

Passo 5: spostare il traffico un client alla volta

Un proxy davanti ai due servizi, o una semplice regola di rete, decide dove va ogni client. Si comincia dal meno critico, quello di un reparto che ti perdona un errore, e si guarda per una settimana. Poi il successivo. I client che non hanno bisogno di nessuna modifica cambiano solo l'indirizzo di destinazione, o nemmeno quello se il nome del server resta uguale.

Passo 6: spegnere il vecchio, ma dopo

Il vecchio server non si spegne il giorno in cui l'ultimo client passa. Si tiene acceso, in sola lettura o fermo, per trenta giorni, il tempo di un'intera chiusura contabile. Solo dopo si archivia la macchina, con un backup verificato e il sorgente in un repository dell'azienda.

Schema dell'affiancamento: i client passano da un proxy che instrada verso il vecchio servizio WCF o verso il nuovo CoreWCF

Il punto di forza dello schema è che ogni passo si può annullare. Se un client si comporta male col servizio nuovo, lo si riporta sul vecchio in cinque minuti e si indaga con calma. Una migrazione che si può annullare a ogni passo si fa in orario di lavoro, senza notti e senza telefonate.

Quanto costa migrare un servizio WCF e quanto tempo serve

Un servizio WCF di medie dimensioni (venti-quaranta operazioni, tre-dieci client, un database) costa dai 12.000 ai 30.000 euro per spostarlo su CoreWCF a contratto invariato, in quattro-otto settimane, e dal doppio al triplo se si sceglie di riscrivere il contratto in REST o gRPC e di adattare i client. I numeri sono stime a 600 euro al giorno, e le voci che li muovono sono sempre le stesse tre.

La prima voce è la qualità del codice esistente. Un servizio con la logica ben separata si sposta in cinque giorni; uno con SQL scritto dentro i metodi di trasporto e variabili statiche condivise ne richiede venti. La seconda è la sicurezza: un servizio con autenticazione Windows integrata e deleghe ha costi molto più alti di uno con una chiave nell'intestazione. La terza è la quantità di client che non si lasciano intatti.

VoceGiorniCosto a 600 euro
Inventario di operazioni, client e sicurezza3-51.800-3.000 euro
Estrazione della logica in libreria4-102.400-6.000 euro
Test sulle chiamate registrate3-61.800-3.600 euro
Servizio CoreWCF e configurazione4-82.400-4.800 euro
Accesso ai dati (EF6 verso EF Core, se serve)0-100-6.000 euro
Affiancamento, passaggio dei client, collaudo5-103.000-6.000 euro
Totale19-4911.400-29.400 euro

Il totale è il motivo per cui scrivo "da dodici a trenta mila". Il preventivo che trovi senza un inventario alle spalle è una scommessa: chi te lo dà o ha già visto il tuo codice, o ha messo dentro un margine di paura.

Il conto a cinque anni

Un servizio non migrato non costa zero. Costa l'ambiente che lo ospita (una macchina virtuale Windows con licenza, circa 1.500-3.000 euro l'anno fra licenza, backup e manutenzione), costa il tempo di chi lo conosce quando serve un intervento e costa il rischio. Su cinque anni la sola macchina vale 7.500-15.000 euro, quasi quanto la migrazione. A questo si somma il fatto che, quando arriverà l'obbligo di spostare tutto, lo farai con meno tempo e con meno margine di trattativa.

Il costo che non appare in nessun preventivo

La conoscenza. Durante la migrazione qualcuno in azienda deve rispondere alle domande: perché questa operazione restituisce così, chi la chiama il venerdì, cosa succede se manca un campo. Se quella persona non c'è, il progetto rallenta di un terzo. Per questo, nei preventivi, chiedo sempre un referente interno per mezza giornata alla settimana: costa poco e fa risparmiare molto.

Per i prezzi dell'intero software, non del solo servizio, i riferimenti sono in quanto costa un software gestionale su misura.

Gli errori che rompono una migrazione da WCF

Gli errori che rompono quasi tutte le migrazioni da WCF sono cinque: cambiare il namespace dei messaggi, perdere il comportamento dei valori nulli, ignorare la sicurezza del vecchio trasporto, sottovalutare i limiti di dimensione dei messaggi e dimenticare le operazioni che gestiscono transazioni. Nessuno è difficile. Tutti si pagano cari se li scopri in produzione.

Il namespace cambiato per sbaglio

Chi crea il nuovo progetto copia l'interfaccia e il generatore di codice propone un namespace nuovo, magari quello dell'azienda aggiornato. Il risultato sono messaggi SOAP che sembrano uguali e non lo sono: gli elementi hanno un prefisso diverso e un client rigoroso li rifiuta. Il test di confronto lo scopre alla prima esecuzione, ma solo se esiste. Per questo i test vengono prima.

I nulli, le date e i decimali

Il serializzatore di .NET Framework e quello moderno trattano in modo leggermente diverso alcuni casi: una stringa nulla contro vuota, una data senza fuso orario, un decimale con molte cifre. Un client scritto vent'anni fa può dipendere da quel comportamento senza saperlo. Le chiamate registrate emergono come differenze, e si decide caso per caso se il nuovo deve imitare il vecchio. Quasi sempre la risposta è sì: la compatibilità batte l'eleganza.

Sicurezza diversa, senza avviso

Un servizio con autenticazione Windows su IIS, spostato su Kestrel in un contenitore Linux, perde per strada l'identità. La migrazione "funziona" e il servizio risponde a tutti, anche a chi non dovrebbe. È l'errore più grave perché non dà errori. La prima domanda di ogni collaudo è: cosa succede se chiamo senza credenziali? La risposta giusta è un rifiuto, e va provata, non supposta.

I limiti dei messaggi

Il web.config vecchio conteneva limiti scelti da qualcuno anni prima: dimensione massima del messaggio, durata delle operazioni, numero di connessioni. Sul servizio nuovo i valori predefiniti sono diversi. Un'operazione che restituisce un elenco di diecimila righe, mai un problema prima, ora si ferma a metà. Si copiano i limiti dall'inventario e si verifica con l'operazione più pesante.

Le transazioni distribuite

Alcuni servizi wrappano un'operazione in una transazione che coinvolge il database e un altro servizio. CoreWCF non la supporta in forma completa. La soluzione è raramente tecnica e quasi sempre di processo: si rende l'operazione ripetibile senza effetti doppi (idempotente), si salva lo stato in una tabella e si completa con un secondo passo. Se l'operazione riguarda denaro o magazzino, questo punto va deciso con chi conosce il processo, non con chi scrive il codice.

Il sesto errore: non avere un piano di ritorno

Non è tecnico ed è il più comune. Chi migra in un fine settimana con il vecchio server spento il lunedì mattina scommette tutto su una prova. Con l'affiancamento descritto prima, ogni giorno ha un piano di ritorno. Con un piano di ritorno, nessuna notte è speciale.

Quando conviene uscire da SOAP: REST e gRPC come passo successivo

CoreWCF è un ponte, non una destinazione: sposta il server su .NET moderno a costo contenuto, e permette di passare a REST o gRPC un client alla volta, quando ha senso, senza fretta e senza interruzioni. Chi lo vive come arrivo definitivo si ritrova fra dieci anni con SOAP nel 2036.

La sequenza che consiglio è in due tempi. Nel primo si porta il servizio su CoreWCF, con il contratto invariato, e si ottiene subito un'infrastruttura moderna, con un ambiente che si aggiorna e un servizio che gira anche in un contenitore. Nel secondo, mentre il servizio vive tranquillo, si affianca una nuova API per le funzioni che servono ai programmi nuovi. Le due convivono, e ogni client migra quando il suo proprietario ha tempo.

REST: la scelta per tutto ciò che guarda il web

Se una funzione serve a un portale, a un'app mobile o a un partner che usa un linguaggio qualunque, una API REST semplice è la scelta naturale. La ricetta moderna è una minimal API che richiama la stessa libreria di logica già estratta; il tema delle scelte è nell'articolo su minimal API o controller in ASP.NET Core. Il costo marginale di una nuova API, avendo già la libreria, è di pochi giorni per gruppo di operazioni.

gRPC: la scelta per i servizi interni

Fra servizi interni che si parlano molto e in fretta, gRPC offre messaggi compatti e contratti tipizzati. Per chi viene da WCF esiste anche la libreria protobuf-net.Grpc, che permette di descrivere i contratti con interfacce C# simili a quelle di WCF, senza scrivere a mano i file di definizione. È una buona strada quando i client sono tutti programmi .NET sotto il tuo controllo. Non lo è per chi deve servire browser o software di terzi.

Come decidere senza fare filosofia

Guardo tre numeri: quanti client nuovi nasceranno nei prossimi due anni, quanti vecchi sono ancora in vita fra tre e se il servizio verrà esposto fuori dall'azienda. Se i client nuovi sono zero e i vecchi restano, CoreWCF basta e conviene fermarsi lì. Se i nuovi sono tanti, la nuova API è un investimento che si ripaga. Il resto è moda.

Chi sta valutando anche l'aggiornamento dell'ambiente attorno troverà utile la data limite che molti dimenticano: la fine del supporto di .NET 8 e .NET 9. Un progetto che parte oggi dovrebbe puntare direttamente a .NET 10, e non perdere tempo con versioni già in scadenza.

L'intelligenza artificiale in una migrazione da WCF: dove aiuta davvero

L'intelligenza artificiale è utile in una migrazione da WCF per leggere il codice che nessuno ricorda, generare i test sulle chiamate registrate e tradurre configurazioni XML in codice; non deve decidere la sicurezza né toccare il contratto pubblico. È uno strumento di velocità, non di giudizio.

Il primo uso è la lettura. Un web.config da seicento righe con tre binding diversi e comportamenti personalizzati si fa spiegare da un assistente in pochi minuti, con un elenco delle voci importanti. Lo trovo utile come prima passata, poi verifico a mano le voci critiche: la sicurezza e i limiti. Il modello è bravo a riassumere e a volte inventa, per questo ogni affermazione che riguarda il comportamento va confermata con una prova.

Il secondo uso è la generazione dei test. Dalle chiamate registrate, un assistente scrive la batteria di confronto e propone casi limite: un campo vuoto, un elenco troppo lungo, un carattere speciale. Quello che serve davvero è decidere cosa si confronta, e quella decisione resta mia. Il terzo uso è la traduzione meccanica: dalle sezioni di configurazione al codice del Program.cs, con regole precise e un controllo finale su ogni voce.

Dove non lo uso

Non lascio decidere all'assistente il modello di sicurezza, perché una svista silenziosa lascia il servizio aperto. Non gli faccio modificare il contratto pubblico, perché ogni lettera in più rompe i client. E non gli chiedo di giudicare la qualità del vecchio codice: serve il giudizio di chi conosce il business. Con questi paletti il tempo risparmiato è reale, circa un quarto dei giorni di lavoro tecnico, e il rischio resta quello di prima.

Domande che ricevo più spesso sulla migrazione da WCF

Le domande ricorrenti sono sei: se Microsoft porterà WCF su .NET 10, se CoreWCF è affidabile in produzione, se i client vecchi continuano a funzionare, quanto dura la migrazione, se si può fare senza interruzioni e se conviene aspettare. Le risposte sono no, sì, sì, dalle quattro alle otto settimane, sì e raramente.

Microsoft porterà mai il server WCF su .NET moderno?

No. Microsoft ha dichiarato da anni che il server WCF resta su .NET Framework e ha indicato CoreWCF come progetto della comunità per chi vuole continuare con quel modello. La parte client invece esiste su .NET moderno e continua a ricevere correzioni.

CoreWCF è abbastanza maturo per la produzione?

Ha superato da tempo la fase sperimentale e viene usato in produzione da grandi aziende. Prima di affidarti ad esso verifica sempre che i binding e le funzioni che usi siano elencati come supportati nella documentazione del progetto, e prova il caso peggiore: la tua operazione più pesante con i dati veri.

I client già installati devono cambiare?

Se il contratto e il namespace restano uguali, no. Un client WCF o un client generato da WSDL vede lo stesso servizio. L'unica cosa che può cambiare è l'indirizzo, e si risolve a livello di rete con un nome di server invariato.

Si può migrare senza fermare l'azienda?

Sì, con l'affiancamento. Il traffico passa dal nuovo servizio client per client, ogni passo si annulla in minuti e il vecchio resta acceso fino alla fine. Una migrazione con una finestra di fermo è quasi sempre un segno di pianificazione povera.

Conviene aspettare ancora un anno?

Dipende da cosa aspetti. Se aspetti che il problema scompaia, non succede. Se aspetti la scadenza naturale del server che lo ospita, valuta bene: quel giorno avrai meno tempo e meno scelta. Il momento migliore è un trimestre tranquillo in cui hai già qualcuno in azienda che conosce il servizio.

Il passo per lunedì

Apri il file di configurazione del tuo servizio WCF più vecchio e conta due cose: quante operazioni espone e quanti client conosci per nome. Se il secondo numero è più basso di quanto ti aspettavi, hai già la prima informazione utile del progetto. Se è zero, hai trovato il motivo per cui conviene muoversi adesso.

Il responsabile IT veronese ha fatto questo esercizio con me. Quattordici client nei log, nove programmi veri, otto operazioni mai chiamate da nessuno. Il servizio nuovo su CoreWCF è andato in affiancamento in cinque settimane, i palmari sono passati per primi e il vecchio eseguibile Delphi, che nessuno poteva toccare, non ha mai saputo che dall'altra parte fosse cambiato qualcosa. Il vecchio server è stato spento dopo la chiusura del mese, e la macchina Windows Server 2012 è uscita dall'inventario senza una riunione.

Se hai un servizio WCF in produzione e non sai da dove cominciare, vieni a parlarne: nel percorso di modernizzazione del software legacy partiamo dall'inventario, stimiamo costo e tempi della strada che si adatta ai tuoi client e decidiamo insieme cosa conviene toccare per primo. La prima conversazione serve a capire se la migrazione ha senso adesso, anche quando la risposta è che puoi aspettare.

La tua azienda ha bisogno di software su misura o di AI nel team?

Progettiamo e sviluppiamo software su misura, modernizziamo i sistemi vecchi e formiamo i tuoi sviluppatori a lavorare con l'AI. Raccontaci il problema: ricevi una risposta concreta entro un giorno lavorativo.

Domande frequenti

No. Il server WCF resta su .NET Framework. Per chi vuole mantenere il modello esiste CoreWCF, progetto della comunità. La parte client invece esiste su .NET moderno.

Sì, è usato in produzione da tempo. Verifica che i binding e le funzioni che usi siano tra quelli supportati e prova l'operazione più pesante con i dati veri.

No, se contratto e namespace restano identici. Può cambiare solo l'indirizzo, e si evita mantenendo lo stesso nome del server.

Per un servizio di medie dimensioni, da 12.000 a 30.000 euro a 600 euro al giorno, in quattro-otto settimane, mantenendo il contratto SOAP. Riscrivere in REST o gRPC costa il doppio o il triplo.

Sì, con l'affiancamento: vecchio e nuovo servizio convivono, i client passano uno alla volta e ogni passo si annulla in pochi minuti.

Di solito no. Prima si porta il server su CoreWCF, poi si affianca una nuova API per i programmi nuovi, quando serve davvero.

Se aspetti che il problema scompaia, no. Il momento migliore è un trimestre tranquillo, finché in azienda c'è ancora chi conosce il servizio.

Lascia i tuoi dati nel form qui sotto

Matteo Migliore

Matteo Migliore è un imprenditore e architetto software con oltre 27 anni di esperienza nello sviluppo di soluzioni basate su .NET e nell'evoluzione di architetture applicative per imprese e organizzazioni di alto profilo.

Nel corso della sua carriera ha collaborato con realtà come Cotonella, Il Sole 24 Ore, FIAT e NATO, guidando team nello sviluppo di piattaforme scalabili e modernizzando ecosistemi legacy complessi.

Ha formato centinaia di sviluppatori e affiancato aziende di ogni dimensione nel trasformare il software in un vantaggio competitivo, riducendo il debito tecnico e portando risultati concreti in tempi misurabili.

Stai leggendo perché vuoi smettere di rattoppare software fragile.Scopri il metodo per progettare sistemi che reggono nel tempo.