Vai al contenuto principale

#c

Da zero a WinUI 3 in 30 minuti: il flusso AI di Microsoft con VS Code, .NET 10 e Copilot

Per anni lo sviluppo di applicazioni desktop native su è stato percepito come un percorso lento: XAML da scrivere a mano, documentazione spar

Altro...

Per anni lo sviluppo di applicazioni desktop native su è stato percepito come un percorso lento: XAML da scrivere a mano, documentazione sparsa tra WPF, UWP e WinUI, e agenti AI generalisti che, interrogati su “come si fa in WinUI 3”, rispondono spesso con pattern deprecati presi da esempi UWP o WPF più vecchi e più numerosi nei dati di addestramento. Microsoft ha da poco pubblicato un flusso di lavoro end-to-end — VS Code, .NET 10 e un agente specializzato — che promette di ridurre il percorso da “cartella vuota” ad app WinUI 3 pubblicabile a circa 30 minuti. Vale la pena capire cosa c’è davvero dietro, perché la parte interessante non è la demo, ma il modo in cui l’agente viene reso affidabile su un framework di nicchia.

Il problema: agenti AI e API deprecateLa documentazione ufficiale lo dice esplicitamente: senza un intervento mirato, un agente AI generico tende a suggerire pattern Windows obsoleti, perché nei dati di addestramento gli esempi WPF e UWP sono semplicemente più numerosi di quelli WinUI 3. La soluzione adottata non è un modello diverso, ma un plugin che inietta regole esplicite su WinUI 3 come istruzioni personalizzate, sovrascrivendo i comportamenti di default del modello. È un approccio replicabile anche in altri contesti: quando un framework è recente o di nicchia, spesso conviene irrigidire l’agente con conoscenza di dominio esplicita piuttosto che sperare che il modello “la sappia già”.

Gli strumenti coinvoltiL’intero flusso si basa su componenti gratuiti:

Visual Studio Code

.NET SDK 10 o successivo

Windows App Development CLI (winapp), il tool a riga di comando per scaffolding, packaging e testing

CLI con estensione Copilot, che richiede un abbonamento GitHub Copilot (è sufficiente il piano gratuito)

Plugin agente WinUI (winui@awesome-copilot)

Estensione WinApp per VS Code

Su Windows l’installazione dei prerequisiti passa quasi interamente da winget:

winget install Microsoft.VisualStudioCode
winget install Microsoft.DotNet.SDK.10
winget install Microsoft.winappcli --source winget
dotnet new install Microsoft.WindowsAppSDK.WinUI.CSharp.Templates
winget install GitHub.cli

gh auth login
gh extension install github/gh-copilot
gh copilot plugin install winui@awesome-copilot

code --install-extension microsoft-winappcli.winapp
winapp --versionL’agente winui-dev e le sue otto skillIl cuore del sistema non è un singolo prompt, ma un pacchetto di otto skill specializzate che l’agente winui-dev orchestra in base al contesto:

winui-setup: verifica e installa i prerequisiti (SDK, template, Developer Mode)

winui--workflow: guida il ciclo scaffold → build → run → iterazione

winui-design: genera layout XAML con i controlli Fluent Design corretti

winui-code-: verifica il codice cercando anti-pattern specifici di WinUI 3

winui-ui-testing: genera test UI basati su Windows UI Automation

winui-packaging: guida su packaging MSIX, firma e pubblicazione in Store

winui-wpf-migration: mappa API WPF verso i corrispondenti WinUI 3

winui-session-report: riassume il lavoro svolto nella sessione

Un dettaglio rilevante per chi lavora già con più strumenti AI: il plugin non è legato a VS Code Copilot Chat. È installabile anche per GitHub Copilot CLI da terminale e, con un registro plugin diverso, per Claude Code:

GitHub Copilot CLI

gh copilot plugin install winui@awesome-copilot
gh copilot plugin list

Claude Code

claude plugin marketplace add microsoft/win-dev-skills
claude plugin install winui@win-dev-skillsIl flusso end-to-end1. Scaffold del progettomkdir MyFirstApp
cd MyFirstApp
dotnet new winui-navviewIl template genera un layout NavigationView con pagine Home, About e Settings già collegate.

  1. Prima esecuzionedotnet runL’app parte come pacchetto “loose layout”, senza bisogno di un’installazione MSIX. Solo dopo il primo dotnet run riuscito conviene aprire VS Code con code .: se si preme F5 prima, il debugger cerca un eseguibile che ancora non esiste.

  2. Aggiungere funzionalità con l’agenteIn VS Code, con Copilot Chat in modalità Agent e l’agente winui-dev selezionato, basta descrivere cosa serve in linguaggio naturale:

Aggiungi una pagina Impostazioni alla mia app WinUI NavigationView
con un interruttore per la modalità scuraL’agente genera i file necessari, aggiorna la struttura di navigazione e, tramite la skill winui-design, produce XAML coerente con i controlli Fluent Design attuali invece di ricorrere a pattern più datati.

  1. PackagingDa un terminale con privilegi elevati (necessario per generare e installare il certificato di sviluppo):

dotnet publish -o ./publish
winapp pack ./publish --generate-cert --install-certPer la sottomissione allo Store, il certificato locale va sostituito con quello fornito da Partner Center.

  1. Pubblicazionewinapp store publish ./*.msix --appId Richiede un account Partner Center attivo; la certificazione richiede tipicamente 1-3 giorni lavorativi.

Cosa considerare prima di adottarlo in produzionePer chi gestisce team .NET, il vantaggio pratico non è tanto il tempo risparmiato sulla prima scaffolding — quello lo si ottiene già con i template dotnet new — quanto la skill winui-code-review, che introduce un controllo automatico contro gli anti-pattern più comuni prima ancora del code review umano, e la skill winui-wpf-migration, utile per chi ha ancora applicazioni WPF legacy da modernizzare in modo incrementale. Resta comunque necessaria una revisione umana del codice generato, in particolare su packaging, firma e permessi richiesti dall’app: sono aspetti che incidono direttamente sulla sicurezza dell’installazione finale.

ConclusioneIl flusso descritto da Microsoft è meno una “demo AI” e più un caso di studio su come rendere affidabile un agente su un dominio verticale: prerequisiti scriptabili, skill specializzate invece di un prompt generico, e un plugin compatibile sia con l’ecosistema GitHub Copilot sia con Claude Code. Per i team che sviluppano o mantengono applicazioni Windows native, è uno stack da provare su un progetto pilota prima di considerarlo parte del flusso standard.

Fonte: 4sysops — approfondimento tecnico basato sulla documentazione ufficiale Microsoft Learn: Quickstart e WinUI agent plugin.

#vscode #windows #c #howto #tutorial #net #copilot

0

Caricamento...

0
2

Caricamento...

WinUI diventa open source: cosa cambia (davvero) per gli sviluppatori .NET

Per anni la community .NET ha guardato con una certa invidia i colleghi che sviluppano su Avalonia UI o Uno Platform: fr

Altro...

Per anni la community .NET ha guardato con una certa invidia i colleghi che sviluppano su Avalonia UI o Uno Platform: framework UI nativi per , ma con il codice sorgente completamente aperto e contribuibile da chiunque. WinUI, il toolkit di interfaccia moderno di Microsoft per applicazioni desktop Windows, è invece rimasto per anni uno sviluppo “a porte chiuse”, con un repository pubblico più che altro simbolico e la vera attività di sviluppo confinata ad interno. Questo sta cambiando, ma con una tabella di marcia più articolata di quanto il titolo delle notizie di questi giorni lasci intendere.

Cos’è WinUI e perché la sua apertura contaWinUI 3 è il motore di rendering e la libreria di controlli su cui si basa il Windows App SDK, l’evoluzione moderna dello stack UI di Windows che ha sostituito (o affiancato, a seconda dei casi) UWP, WPF e Windows Forms per le applicazioni desktop native più recenti. È il framework consigliato da Microsoft per chi scrive nuove applicazioni Windows in C#/.NET con un’interfaccia utente moderna, fluida e coerente con il design system di Windows 11.

Il problema storico è che, pur essendo distribuito come pacchetto NuGet open source, lo sviluppo effettivo del codice avveniva internamente. Il repository microsoft/microsoft-ui-xaml serviva principalmente per il tracciamento delle issue, non per contributi di codice reali. Questo ha generato negli anni frustrazione attorno a problemi noti e mai risolti: supporto incompleto per i valori decimali nel controllo NumberBox, finestre di dialogo modali poco affidabili, gap nella validazione degli input, l’assenza di un designer visuale integrato in Visual Studio e prestazioni non sempre all’altezza rispetto alla vecchia UWP.

Il piano a quattro fasiMicrosoft ha pubblicato la roadmap dell’apertura in una discussion ufficiale sul repository, ed è organizzata in quattro fasi progressive, non in un singolo “flip the switch”:

Fase 1 (completata, ott. 2025)
→ aumento della frequenza di mirroring da Azure DevOps a GitHub:
i commit interni diventano visibili quasi in tempo reale

Fase 2 (completata, dic. 2025)
→ gli sviluppatori esterni possono clonare il repository e
compilarlo in locale, con documentazione sulle dipendenze

Fase 3 (completata, mag. 2026)
→ i contributor possono aprire pull request (mirrorate
internamente) ed eseguire la test suite in locale;
il team ha districato le dipendenze private e reso
pubblica l'infrastruttura di test

Fase 4 (in corso, target set. 2026)
→ GitHub diventa l'hub di sviluppo primario, eliminando
il mirroring interno come centro di gravità del progetto
Ad oggi ci troviamo quindi tra la fase 3 e la fase 4: il codice è realmente visibile e buildabile, ma il flusso di contribuzione della community non è ancora quello “GitHub-native” a cui si è abituati con altri progetti open source Microsoft come .NET stesso o VS Code.

Cosa si può fare concretamente oggiPer chi vuole già mettere le mani sul codice, i requisiti pratici per compilare WinUI in locale sono non banali: circa 80 GB di disco libero e almeno 32 GB di RAM per una build confermata funzionante. Non è un progetto leggero da compilare su un di fascia media.

git clone https://github.com/microsoft/microsoft-ui-xaml.git
cd microsoft-ui-xaml

seguire la documentazione del repository per le

dipendenze del toolchain e i target di build supportati

Il branch principale (winui3/main) riceve tuttora sincronizzazioni dirette da Azure DevOps, quindi è aggiornato ma non ancora il punto di partenza esclusivo dello sviluppo. La test suite è ora eseguibile pubblicamente, il che permette di verificare in autonomia se una patch personalizzata introduce regressioni prima di proporla come contributo.

Cosa resta chiuso, e perchéNon tutto lo stack diventerà pubblico nel breve termine. WinUI ha “radici profonde” in componenti proprietari del sistema operativo, e alcune aree restano fuori dal perimetro di apertura, almeno per ora:

Il compilatore XAML: è il focus dichiarato della fase 4, ma resta per ora un componente interno.

La compilazione dei pacchetti MSIX: strettamente legata alla toolchain di packaging di Windows.

Alcuni layer di gestione input: in particolare Microsoft.UI.Input.dll è indicato esplicitamente come area problematica da aprire, per via delle dipendenze con sottosistemi Windows non pubblici.

Beth Pan, una delle maintainer del progetto, ha descritto il processo con una frase che vale la pena riportare: non è “un interruttore da girare”, ma un percorso deliberato. È un’aspettativa realistica da tenere a mente prima di proporre la prima pull request pensando di vederla mergeata in tempi brevi.

Come si posiziona rispetto alle alternativePer chi sta scegliendo oggi un framework UI desktop per .NET, un confronto rapido aiuta a inquadrare la novità:

WinUI 3 / Windows App SDK: nativo Windows, massima integrazione col design system Windows 11, ora in fase di apertura ma sviluppo ancora a trazione Microsoft; solo Windows.

Avalonia UI: completamente open source da anni, cross-platform (Windows, Linux, macOS), community di contributor esterni consolidata, look and feel personalizzabile via XAML-like styling.

Uno Platform: nato come porting di UWP/WinUI verso altre piattaforme (inclusi WebAssembly e mobile), open source, spesso scelto proprio da chi vuole la sintassi WinUI ma con vera portabilità multipiattaforma.

.NET MAUI: soluzione ufficiale Microsoft per mobile e desktop cross-platform, con un modello a controlli nativi per piattaforma anziché un motore di rendering condiviso come Avalonia.

L’apertura di WinUI non cambia immediatamente questo quadro competitivo, ma riduce un differenziale reale: la trasparenza sullo sviluppo. Poter vedere le pull request in corso, le decisioni di design discusse pubblicamente e i problemi di performance affrontati in tempo reale è un beneficio concreto anche per chi non contribuirà mai una riga di codice, perché permette di valutare con più cognizione di causa se e quando un problema noto (penso al supporto NumberBox o alla stabilità dei dialoghi modali) verrà effettivamente risolto.

ConclusioneChi sviluppa applicazioni desktop Windows in .NET dovrebbe iniziare a seguire da vicino il repository microsoft/microsoft-ui-xaml, non tanto per proporre subito una pull request quanto per avere finalmente visibilità reale sulla roadmap tecnica del framework che probabilmente sta già usando in produzione. La fase 4, attesa per settembre 2026, sarà il vero banco di prova: se GitHub diventerà davvero il centro di sviluppo primario, WinUI potrà iniziare a colmare il gap di fiducia accumulato in anni di sviluppo chiuso rispetto a progetti come Avalonia. Fino ad allora, vale la pena testare la build locale e valutare in autonomia lo stato di salute del progetto, invece di affidarsi solo agli annunci ufficiali.

Fonte: 4sysops.com. Dettagli tecnici sulla roadmap: GitHub Discussion #10700. Documentazione ufficiale: Microsoft Learn — WinUI 3.

#microsoft #windows #c #net #dev

1

Caricamento...

0
1

Caricamento...

Un agente AI è un sistema distribuito, non un chatbot: pattern di durable orchestration in .NET

Negli ultimi mesi molti team hanno scoperto a proprie spese che il problema più grande di un agente AI in produzione non è la qualità del prompt, ma l

Altro...

Negli ultimi mesi molti team hanno scoperto a proprie spese che il problema più grande di un agente AI in produzione non è la qualità del prompt, ma la sua affidabilità operativa. Un articolo recente su DZone, “Your AI Agent Is a Distributed System, Not a Chatbot”, mette a fuoco un punto che chi progetta sistemi backend conosce bene da anni: se un componente deve sopravvivere a crash, timeout, retry e attese umane di ore, non puoi trattarlo come una semplice chiamata sincrona a un modello. Devi trattarlo come un sistema distribuito, con tutto ciò che questo comporta: stato persistente, checkpoint, idempotenza e recovery.

In questo articolo riprendiamo quei concetti e li caliamo nella pratica con .NET, mostrando come Azure Durable Functions (o alternative come Temporal) permettano di costruire agenti AI multi-step che non perdono lo stato quando qualcosa va storto — cosa che, in produzione, prima o poi succede sempre.

Perché un chatbot stateless non bastaUn chatbot classico è un ciclo request/response: l’utente scrive, il modello risponde, fine. Un agente AI enterprise, invece, tipicamente deve:

orchestrare più chiamate a modelli e strumenti in sequenza o in parallelo;

interrogare sistemi esterni (CRM, ticketing, knowledge base, database);

attendere l’approvazione di un umano, che può richiedere minuti oppure ore;

gestire fallimenti parziali senza dover ripartire da zero;

garantire che un’azione con effetti collaterali (un rimborso, un invio email, una scrittura su un sistema esterno) non venga eseguita due volte per colpa di un retry.

Nessuno di questi requisiti è nuovo: sono gli stessi problemi che i sistemi distribuiti risolvono da decenni con pattern come saga, checkpointing e idempotency key. La differenza è che oggi il “servizio downstream” spesso è un LLM, e la latenza dominante non è più quella di rete, ma quella dell’attesa umana.

Durable orchestration: lo stato che sopravvive al crashIl pattern architetturale proposto è un runtime di orchestrazione durevole, che mantiene lo stato del workflow indipendentemente dal ciclo di vita del processo che lo esegue. In .NET, l’implementazione più diretta è Azure Durable Functions, che introduce tre concetti chiave:

Orchestrator function: decide “cosa succede dopo”, applica le retry policy e coordina le chiamate, ma non esegue lavoro con effetti collaterali direttamente;

Activity function: esegue il lavoro reale (chiamata al modello, query, side effect) ed è il livello dove si applica l’idempotenza;

Checkpointing automatico: dopo ogni await, il runtime salva lo stato dell’orchestrazione, così un crash del processo non fa perdere il progresso già fatto.

Un’alternativa nota, citata anche nell’articolo originale, è Temporal, che applica lo stesso principio con un modello di programmazione simile ma un runtime a sé stante, spesso preferito in contesti multi-linguaggio o Kubernetes-native.

Il pattern fan-out/fan-in per agenti multipliQuando un task richiede il contributo di più agenti specializzati (per esempio: un agente diagnostico, uno di ricerca sulla knowledge base, uno che consulta lo storico dei casi e uno che verifica le policy aziendali), il pattern corretto è il fan-out/fan-in: l’orchestratore lancia tutte le attività in parallelo e aggrega i risultati solo quando sono tutte terminate.

Ecco un esempio realistico in C# con il modello isolato di Azure Functions, ispirato agli esempi ufficiali Microsoft:

[Function("SupportInvestigationOrchestrator")]
public static async Task<InvestigationResult> Run(
[OrchestrationTrigger] TaskOrchestrationContext context)
{
var caseId = context.GetInput();

// Fan-out: 4 agenti specializzati lanciati in parallelo
var diagnosticTask = context.CallActivityAsync<AgentFinding>(
    "RunDiagnosticAgent", caseId);
var knowledgeTask = context.CallActivityAsync<AgentFinding>(
    "RunKnowledgeSearchAgent", caseId);
var historyTask = context.CallActivityAsync<AgentFinding>(
    "RunHistoricalCaseAgent", caseId);
var policyTask = context.CallActivityAsync<AgentFinding>(
    "RunPolicyAgent", caseId);

// Fan-in: si attende che tutti i task completino
AgentFinding[] findings = await Task.WhenAll(
    diagnosticTask, knowledgeTask, historyTask, policyTask);

// Sintesi della raccomandazione finale
var recommendation = await context.CallActivityAsync<Recommendation>(
    "SynthesizeRecommendation", findings);

return new InvestigationResult(caseId, findings, recommendation);

}Il vantaggio rispetto a un semplice Task.WhenAll in un servizio stateless è che, se il processo host crasha mentre due agenti su quattro hanno già risposto, l’orchestrazione riparte dal checkpoint e non richiama gli agenti già completati.

Human-in-the-loop senza tenere aperta la computeIl collo di bottiglia più comune non è il modello, ma l’attesa di un’approvazione umana. Un workflow che tenesse una funzione serverless “in ascolto” per ore sarebbe insostenibile in termini di costo e di timeout. Il pattern corretto è sospendere l’orchestrazione in attesa di un evento esterno:

[Function("SupportInvestigationOrchestrator")]
public static async Task<InvestigationResult> Run(
[OrchestrationTrigger] TaskOrchestrationContext context)
{
// ... fan-out/fan-in come sopra ...

await context.CallActivityAsync("NotifyHumanReviewer", recommendation);

// Il workflow si sospende senza consumare risorse compute
// fino a quando l'evento non arriva, anche dopo diverse ore
var decision = await context.WaitForExternalEvent<HumanReviewDecision>(
    "HumanReviewCompleted");

if (decision.Approved)
{
    await context.CallActivityAsync("ApplyResolution", recommendation);
}

return new InvestigationResult(caseId, findings, recommendation, decision);

}L’evento viene “consegnato” all’orchestrazione in pausa tramite una chiamata separata (per esempio da una Function HTTP-triggered collegata a un pulsante “Approva” nella UI), e il runtime si occupa di riprendere l’esecuzione esattamente dal punto in cui era stata sospesa.

Idempotenza: il vero rischio nascostoUn runtime durevole garantisce tipicamente semantica at-least-once: dopo un crash, un’attività può essere rieseguita. Questo va benissimo per operazioni pure (una query di lettura), ma è pericoloso per operazioni con side effect (un rimborso, un invio email, una scrittura irreversibile). Il momento critico è il cosiddetto crash window: l’intervallo tra il completamento effettivo di un’azione e il salvataggio del suo checkpoint.

La soluzione è associare a ogni operazione critica una idempotency key deterministica, così che una riesecuzione accidentale venga riconosciuta e ignorata a livello applicativo:

[Function("ApplyGoodwillRefund")]
public static async Task ApplyGoodwillRefund(
[ActivityTrigger] RefundRequest request)
{
string idempotencyKey = $"{request.CaseId}:goodwill-refund";

if (await _paymentService.WasAlreadyProcessedAsync(idempotencyKey))
{
    return; // operazione già eseguita, nessun effetto collaterale duplicato
}

await _paymentService.ProcessRefundAsync(request, idempotencyKey);

}Questo pattern, ben noto a chi lavora con gateway di pagamento, va applicato sistematicamente a ogni activity che tocchi sistemi esterni non idempotenti per natura.

Successo parziale, non tutto-o-nienteSe uno dei quattro agenti fallisce (per esempio, il servizio di knowledge search va in timeout), il sistema non dovrebbe far fallire l’intera indagine. Meglio trattare i risultati come esiti strutturati, distinguendo tra “successo”, “fallito” e “degradato”, e permettere che la sintesi finale proceda comunque, segnalando esplicitamente quali fonti mancano:

public record AgentFinding(
string AgentName,
AgentStatus Status, // Success, Failed, Degraded
string? Result,
string? FailureReason);Questo approccio “graceful degradation” è preferibile a un fallimento totale che obbliga a rieseguire da capo un’indagine costosa in termini di tempo e token consumati.

Osservabilità come requisito di prodottoIn un sistema dove un’indagine può durare ore e coinvolgere quattro o più agenti, la tracciabilità non è un dettaglio tecnico: è parte dell’esperienza utente e, in molti contesti regolamentati, un requisito di audit. Vale la pena tracciare sistematicamente:

workflow instance ID, correlation ID e case ID;

lo stage corrente e la durata di ogni singolo agente;

il numero di retry e il motivo di ogni fallimento;

la latenza di revisione umana (spesso il fattore dominante);

la tracciabilità delle evidenze usate per la raccomandazione finale, per scopi di audit.

ConclusioneIl messaggio di fondo è semplice ma spesso trascurato: il workflow conta più del prompt. Un agente AI ben progettato non è quello con il prompt più raffinato, ma quello costruito su un runtime capace di sopravvivere a crash, gestire attese umane di ore senza sprecare risorse, ed evitare effetti collaterali duplicati. Per chi lavora nello stack .NET, Azure Durable Functions offre oggi gli strumenti necessari per applicare questi pattern senza dover reinventare un motore di orchestrazione da zero; per contesti poliglotta o già containerizzati, Temporal resta un’alternativa solida con la stessa filosofia.

Fonte originale: “Your AI Agent Is a Distributed System, Not a Chatbot” su DZone.

#ai #ia #microsoft #c #net #azure #dev

0

Caricamento...

0
1

Caricamento...

Crittografia post-quantistica: perché il threat modeling non può più aspettare (con esempi in .NET 10)

C’è una minaccia alla crittografia moderna che non richiede un computer quantistico funzionante oggi per essere reale oggi: si chiama “harvest now, de

Altro...

C’è una minaccia alla crittografia moderna che non richiede un computer quantistico funzionante oggi per essere reale oggi: si chiama “harvest now, decrypt later” (raccogli ora, decifra dopo). Un attaccante con risorse sufficienti — uno stato-nazione, tipicamente — può intercettare e archiviare traffico cifrato con RSA o ECC adesso, per poi decifrarlo tra qualche anno, quando computer quantistici sufficientemente potenti saranno disponibili. Per dati con un ciclo di vita lungo — segreti industriali, cartelle cliniche, comunicazioni diplomatiche, chiavi di firma di lungo periodo — la finestra di esposizione è già aperta, anche se il computer quantistico “rompi-RSA” non esiste ancora.

È in questo contesto che Microsoft ha recentemente pubblicato una guida al threat modeling applicato specificamente alla migrazione verso la crittografia post-quantistica (PQC), invitando organizzazioni e team di sviluppo a non aspettare la disponibilità degli algoritmi per cominciare a muoversi.

Perché serve il threat modeling, e non solo un elenco di algoritmiIl problema centrale che Microsoft evidenzia non è tecnico in senso stretto, è organizzativo: la maggior parte delle aziende non ha un inventario completo di dove e come viene usata la crittografia nei propri sistemi. Certificati TLS, librerie di firma incorporate in applicazioni legacy, hardware embedded con chiavi hard-coded, protocolli proprietari che usano RSA “perché si è sempre fatto così” — sono tutte dipendenze crittografiche nascoste che un aggiornamento generico non intercetta.

Il threat modeling applicato alla PQC serve esattamente a questo: mappare asset, flussi di dati, confini di fiducia (trust boundary) e controlli di sicurezza esistenti per far emergere queste dipendenze prima che diventino un problema urgente sotto pressione regolatoria o, peggio, sotto attacco. Concretamente, significa rispondere a domande come: quali sistemi cifrano dati che devono restare confidenziali per più di 5-10 anni? Quali certificati di firma del codice hanno una validità che si estende oltre il 2030? Quali protocolli interni non supportano l’agilità crittografica, cioè non permettono di sostituire un algoritmo senza riscrivere l’applicazione?

Gli algoritmi: da NIST a nomi che iniziano a essere familiariDopo anni di standardizzazione, il NIST ha pubblicato tre standard che è ormai il momento di conoscere, perché stanno entrando nei prodotti che usiamo quotidianamente:

ML-KEM (Module-Lattice Key Encapsulation Mechanism, FIPS 203) — sostituisce lo scambio di chiavi basato su RSA o curve ellittiche (ECDH). È l’algoritmo che entra in gioco nell’handshake TLS per stabilire un segreto condiviso.

ML-DSA (Module-Lattice Digital Signature Algorithm, FIPS 204) — l’algoritmo di firma digitale post-quantistico, pensato come sostituto di RSA e ECDSA per firmare certificati, codice e messaggi.

SLH-DSA (Stateless Hash-Based Digital Signature Algorithm, FIPS 205) — un algoritmo di firma alternativo, basato su funzioni hash anziché su reticoli, pensato come backup conservativo nel caso in cui in futuro emergano debolezze crittanalitiche nei problemi su reticolo.

Sul fronte delle raccomandazioni pratiche, Microsoft insiste su un punto spesso sottovalutato: la migrazione a TLS 1.3 è il prerequisito, non un dettaglio. TLS 1.2 non supporta i meccanismi ibridi necessari per introdurre ML-KEM accanto agli algoritmi classici, e restare su TLS 1.2 significa restare bloccati fuori dalla transizione PQC anche quando gli algoritmi saranno pronti. In parallelo, si consiglia di alzare l’asticella anche sulla crittografia simmetrica e sulle funzioni hash, adottando AES-256 e SHA-384 come standard, per mantenere margini di sicurezza adeguati anche in scenari quantistici (dove alcuni attacchi, come Grover, dimezzano di fatto la sicurezza effettiva degli algoritmi simmetrici).

La timeline che Microsoft si è data per la transizione dei propri prodotti e servizi critici è il 2029 — una data che vale la pena tenere a mente come riferimento di settore, anche per pianificare le proprie migrazioni interne con lo stesso ordine di grandezza.

Cosa c’è già oggi: le API disponibiliLa parte più interessante per chi scrive codice è che la PQC non è più solo teoria da paper accademico: le API sono già disponibili e generalmente disponibili (GA) sulle piattaforme Microsoft.

Windows: CNGSu Windows, il supporto arriva a livello di CNG (Cryptography API: Next Generation), con identificatori di algoritmo dedicati per ML-KEM e ML-DSA utilizzabili tramite le funzioni BCryptGenerateKeyPair e le relative API di key exchange e firma. Il supporto nativo è arrivato a partire da Windows 11 con gli aggiornamenti di novembre 2025: chi gestisce flotte Windows dovrebbe verificare di essere allineato con le patch più recenti prima di pianificare qualunque test.

.NET 10: MLKem e MLDsa in System.Security.CryptographyPer chi sviluppa in C#, la notizia più concreta è l’arrivo delle classi MLKem e MLDsa direttamente in System.Security.Cryptography con .NET 10. Ecco un esempio minimo di key encapsulation:

using System.Security.Cryptography;

if (!MLKem.IsSupported)
{
Console.WriteLine("ML-KEM non è supportato su questa piattaforma");
return;
}

MLKemAlgorithm alg = MLKemAlgorithm.MLKem768;

using (MLKem privateKey = MLKem.GenerateKey(alg))
using (MLKem publicKey = MLKem.ImportEncapsulationKey(
alg, privateKey.ExportEncapsulationKey()))
{
publicKey.Encapsulate(out byte[] ciphertext, out byte[] sharedSecret1);
byte[] sharedSecret2 = privateKey.Decapsulate(ciphertext);

bool match = sharedSecret1.AsSpan().SequenceEqual(sharedSecret2);
Console.WriteLine($"I segreti condivisi coincidono: {match}");

}E un esempio di firma con ML-DSA:

MLDsaAlgorithm alg = MLDsaAlgorithm.MLDsa65;

using (MLDsa key = MLDsa.GenerateKey(alg))
{
byte[] data = "Messaggio da firmare"u8.ToArray();
byte[] signature = new byte[alg.SignatureSizeInBytes];

key.SignData(data, signature);
bool verified = key.VerifyData(data, signature);

Console.WriteLine($"Firma verificata: {verified}");

}Entrambe le famiglie di algoritmi sono disponibili in più varianti — MLKem512, MLKem768, MLKem1024 per il key encapsulation, e MLDsa44, MLDsa65, MLDsa87 per la firma — con un compromesso crescente tra sicurezza e dimensione delle chiavi. Ad esempio, per MLDsa65 la chiave pubblica occupa 1952 byte, quella privata 4032 byte e la firma 3309 byte: numeri sensibilmente più grandi rispetto a ECDSA, un dettaglio da tenere presente quando si progettano protocolli o formati di messaggio con vincoli di banda o storage.

Un paio di note pratiche per chi vuole sperimentare da subito: su Linux serve OpenSSL 3.5 o superiore, mentre chi è ancora su .NET Standard 2.0 può accedere alle stesse API tramite il pacchetto NuGet Microsoft.Bcl.Cryptography. Per il supporto lato TLS 1.3, certificati basati su ML-DSA e SLH-DSA funzionano già in scenari di autenticazione quando sia il sistema operativo sia la controparte della connessione supportano i nuovi algoritmi — un altro motivo per cui la coordinazione tra client e server nella transizione non è opzionale.

Da dove cominciare, in praticaPer un team che affronta questo tema per la prima volta, un percorso ragionevole è: primo, effettuare un inventario reale di certificati, librerie crittografiche e protocolli in uso, distinguendo per criticità e durata di vita dei dati protetti; secondo, verificare che l’infrastruttura TLS sia già su 1.3 ovunque possibile, perché è il prerequisito tecnico per tutto il resto; terzo, iniziare a sperimentare le nuove API — su .NET 10 il costo di ingresso è basso, si tratta di poche righe di codice — in ambienti non di produzione, per capire l’impatto su dimensioni di chiavi, firme e tempi di calcolo prima che diventi un requisito con scadenza stretta.

La crittografia post-quantistica non è ancora un’emergenza operativa per la maggior parte delle organizzazioni, ma il messaggio di Microsoft è chiaro: il momento di mappare le proprie dipendenze crittografiche e cominciare a testare gli algoritmi è adesso, non quando arriverà l’obbligo normativo o il primo incidente.

Fonte originale: Microsoft Urges Threat Modeling to Prepare for Post-Quantum Cryptography Migration, Petri IT Knowledgebase

#sicurezza #microsoft #windows #c #net

1

Caricamento...

0
1

Caricamento...

Unity abbandona Mono per CoreCLR: cosa cambia con .NET 10 e C# 14

Da Mono a CoreCLR: la fine di un’era per UnitySe sviluppate in C# ma non toccate Unity, la notizia potrebbe sembrarvi di nicchia. Non lo è. Con la rel

Altro...

Da Mono a CoreCLR: la fine di un’era per UnitySe sviluppate in C# ma non toccate Unity, la notizia potrebbe sembrarvi di nicchia. Non lo è. Con la release di Unity 6.8, prevista entro la fine del 2026, il motore di gioco più diffuso al mondo abbandona definitivamente il proprio fork custom di Mono in favore di CoreCLR, il runtime “vero” del .NET moderno, con supporto a .NET 10 e C# 14. Per anni Unity è rimasto ostaggio di un’architettura di scripting congelata a metà del decennio scorso, mentre il resto dell’ecosistema .NET correva avanti tra top-level statements, pattern matching avanzato, source generator e miglioramenti di performance del JIT. Il cambio di runtime non è solo un aggiornamento di versione: è un caso di studio interessante per chiunque lavori con .NET, anche fuori dal game dev, perché racconta come si affronta la migrazione di un’applicazione legacy da AppDomain a un modello di isolamento moderno.

Domain Reload: il problema che ogni sviluppatore Unity conosce a memoriaChi lavora su progetti Unity di dimensioni consistenti conosce fin troppo bene il Domain Reload: si salva uno script, si torna nell’editor, e parte una barra di progresso che su progetti grandi può durare decine di secondi. Il motivo è architetturale: ogni ricompilazione degli script comporta lo scaricamento completo dell’AppDomain e il suo ricaricamento da zero in memoria, un’operazione “a tappeto” pensata per un modello di isolamento vecchio di vent’anni.

Con CoreCLR, Unity abbandona il concetto di AppDomain in favore degli AssemblyLoadContext (ALC), il meccanismo di isolamento e caricamento assembly introdotto nel .NET moderno fin dai tempi di .NET Core. Invece di ricaricare tutto lo stato applicativo, il runtime può scaricare e ricaricare selettivamente solo gli assembly effettivamente modificati.

AssemblyLoadContext: un concetto utile ben oltre UnityPer chi non l’avesse mai usato fuori da un contesto plugin-system, un AssemblyLoadContext è essenzialmente un contenitore isolato in cui caricare assembly .NET, che può essere scaricato indipendentemente dal resto dell’applicazione. È lo stesso meccanismo che sta dietro a scenari come plugin dinamici, hot reload di parti di un’applicazione server, o sandboxing di codice di terze parti. Un esempio minimale, applicabile a qualunque applicazione .NET moderna:

using System.Reflection;
using System.Runtime.Loader;

var alc = new AssemblyLoadContext("PluginContext", isCollectible: true);

Assembly plugin = alc.LoadFromAssemblyPath(@"C:\plugins\MyPlugin.dll");
// ... usa il plugin tramite reflection o interfacce condivise ...

alc.Unload(); // richiede la garbage collection per liberare davvero la memoria
GC.Collect();
GC.WaitForPendingFinalizers();
Il dettaglio da tenere presente, sia in Unity sia in un’applicazione .NET qualsiasi, è che uno scaricamento “leaked” è possibile: se un riferimento a un tipo caricato nell’ALC sopravvive fuori dal suo scope (una closure, un evento sottoscritto, un campo statico), l’assembly non può essere effettivamente liberato dal garbage collector. Non a caso, nel forum ufficiale Unity gli sviluppatori hanno confermato che il motore segnalerà esplicitamente all’utente quando un AssemblyLoadContext non riesce a essere scaricato correttamente, un problema di leak molto simile a quello che chi scrive plugin system in .NET conosce già.

Cosa cambia in pratica, oltre al Domain ReloadLa migrazione a CoreCLR porta con sé una serie di conseguenze pratiche per chi sviluppa con Unity:

ECS più integrato: gli Instance ID passano da 32 a 64 bit, permettendo a GameObject “classici” ed entità ECS (Data-Oriented Technology Stack) di condividere lo stesso spazio di identificatori. Un nuovo metodo GetEntityId() collega direttamente gli oggetti di scena al mondo ECS, riducendo la frizione tra i due paradigmi.

Serializzazione nativa dei dizionari: Dictionary<TKey, TValue> sarà finalmente serializzabile nativamente dall’Inspector, eliminando i workaround basati su liste parallele di chiavi e valori o su ISerializationCallbackReceiver. In parallelo, Unity rimuove il datato e insicuro BinaryFormatter.

IL2CPP resta, ma diventa opzionale: per le piattaforme non coperte da NativeAOT (che CoreCLR usa per la compilazione ahead-of-time), IL2CPP continuerà a essere il backend di scripting necessario. Su piattaforme compatibili, però, sarà possibile scegliere CoreCLR come backend alternativo già a partire da una preview tecnica prevista intorno a Unity 6.7.

MiMalloc come allocatore di memoria: l’integrazione dell’allocatore ad alte prestazioni di Microsoft riduce i problemi di lock contention nei carichi multithread, con benefici diretti per chi usa il C# Job System in scenari data-oriented.

Perché la cosa interessa anche chi non fa game devIl percorso di Unity da Mono a CoreCLR è, in piccolo, lo stesso tipo di migrazione che molte software house con applicazioni .NET Framework legacy dovranno affrontare prima o poi: passare da un modello di isolamento basato su AppDomain (o peggio, da un fork custom del runtime) a un’architettura moderna basata su ALC, con tutti i vantaggi in termini di performance, ma anche le insidie legate alla gestione del ciclo di vita degli assembly caricati dinamicamente. Se lavorate su plugin system, hosting di codice di terze parti o architetture a moduli scaricabili a runtime, vale la pena studiare da vicino come Unity gestisce concretamente i leak di ALC: è un problema che, presto o tardi, si incontra in qualunque applicazione .NET che provi a fare hot-reload o isolamento dinamico.

ConclusioneCon Unity 6.8, il motore smette di essere un’isola separata dall’ecosistema .NET e si allinea finalmente al runtime moderno, portando in dote C# 14, prestazioni migliori e un developer loop molto più rapido. Per chi sviluppa giochi è una notizia enorme; per chi sviluppa in .NET in generale è un promemoria utile su come affrontare, con gli strumenti giusti, la migrazione da architetture di isolamento legacy a AssemblyLoadContext.

Fonte: DZone, con dettagli tecnici dal thread ufficiale Path to CoreCLR, 2026: Upgrade Guide su Unity Discussions.

#c #programmazione #net #dev

0

Caricamento...

0
1

Caricamento...

C# 15 introduce le union: basta OneOf e Results per modellare i tipi (.NET 11 Preview 6)

Da anni gli sviluppatori C# aspettano un modo nativo per dire “questo valore è esattamente uno tra questi tipi, e nient’altro”, con il compilatore in

Altro...

Da anni gli sviluppatori C# aspettano un modo nativo per dire “questo valore è esattamente uno tra questi tipi, e nient’altro”, con il compilatore in grado di garantirlo. In assenza di un supporto di linguaggio, la community si è arrangiata con pattern come Results<T> di ASP.NET Core Minimal API o con librerie come OneOf. Funzionano, ma con un limite strutturale: se aggiungi un quarto caso possibile a una funzione che prima ne restituiva tre, nessuno ti avvisa che uno switch a valle non gestisce il nuovo tipo. Manca l’esaustività, che è poi il punto centrale delle discriminated union.

Con .NET 11 Preview 6 (rilasciata il 14 luglio 2026) e C# 15, questa lacuna si chiude: arriva la parola chiave union, insieme a un intero pacchetto di funzionalità correlate (conversioni implicite, pattern matching esaustivo, gestione della nullabilità) che rendono i union type un cittadino di prima classe del linguaggio.

La sintassi: dichiarare un union typeLa forma più semplice è la union declaration, una sintassi compatta che genera automaticamente uno struct:

public union Pet(Cat, Dog, Bird);Questa singola riga dice al compilatore che un Pet è esattamente un Cat, un Dog o un Bird, e nient’altro. Sotto il cofano, il compilatore genera uno struct che implementa l’interfaccia System.Runtime.CompilerServices.IUnion e conserva il valore effettivo in una proprietà Value di tipo object?.

I union generici sono immediatamente utili per modellare risultati di operazioni che possono fallire, un caso d’uso ricorrentissimo in codice di produzione:

public union Result<TSuccess, TError>(TSuccess, TError);

Result<User, Error> Register(string username)
{
if (string.IsNullOrEmpty(username))
return new Error("Username cannot be empty");

return new User(username);

}Da notare l’ultima riga: nessun wrapping esplicito, nessuna chiamata a un factory method. Il valore User o Error viene convertito implicitamente in Result<User, Error> grazie alle union conversion generate automaticamente per ogni case type.

Pattern matching esaustivo, finalmenteIl vero salto di qualità è nel matching. Se dimentichi un caso in uno switch su un union type, il compilatore te lo dice:

string Describe(Pet pet) => pet switch
{
Dog d => d.Name,
Cat c => c.Name,
// CS8509: switch expression does not handle all
// possible values of its input type (Bird)
};Aggiungendo il caso mancante, l’avviso scompare, e non serve più il classico _ => throw new InvalidOperationException("unreachable") per zittire il compilatore:

string Describe(Pet pet) => pet switch
{
Dog d => d.Name,
Cat c => c.Name,
Bird b => b.Name,
};Il punto interessante è che questa esaustività è dinamica: se in futuro aggiungi un nuovo case type al union (per esempio un quarto animale), ogni switch esistente che non lo gestisce si illumina di un warning. Per chi ha inseguito bug di produzione causati da un case dimenticato in un evento di dominio, è un cambiamento non da poco.

I pattern si applicano direttamente al union, senza bisogno di accedere manualmente a .Value: il compilatore effettua l’unwrapping in automatico, anche negli if pattern classici:

if (pet is Dog d)
{
Console.WriteLine(d.Name);
}Gestione del nullIl valore di default di un union type ha Value == null, ed è possibile intercettarlo esplicitamente con il pattern null:

string Describe(Pet pet) => pet switch
{
null => "nessun animale",
Dog d => d.Name,
Cat c => c.Name,
Bird b => b.Name,
};La necessità o meno del ramo null dipende dal fatto che il parametro o il campo union-typed sia nullable: l’analisi di nullabilità del compilatore guida correttamente questi casi, in coerenza con le annotazioni enable già in uso nella maggior parte delle codebase moderne.

Un caso pratico: modellare eventi di dominioI union type diventano davvero interessanti quando li si combina con i record per il domain modeling, per esempio in un sistema di elaborazione ordini con eventi distinti:

public record OrderPlaced(Guid OrderId, decimal Total);
public record OrderShipped(Guid OrderId, string TrackingNumber);
public record OrderCancelled(Guid OrderId, string Reason);
public union OrderEvent(OrderPlaced, OrderShipped, OrderCancelled);

string Summarize(OrderEvent evt) => evt switch
{
OrderPlaced p => $"Ordine {p.OrderId} piazzato per {p.Total:C}",
OrderShipped s => $"Ordine {s.OrderId} spedito, tracking: {s.TrackingNumber}",
OrderCancelled c => $"Ordine {c.OrderId} annullato: {c.Reason}",
};Quando tra tre mesi qualcuno aggiungerà OrderRefunded al union, ogni handler che non lo gestisce lancerà un warning in fase di compilazione, invece di fallire silenziosamente in produzione. È il compilatore che fa da revisore di esaustività al posto tuo.

I union possono anche esporre metodi e proprietà calcolate (ma non campi d’istanza), utile per incapsulare logica di conversione:

public union Length(Meters, Feet)
{
public double TotalMeters => this switch
{
Meters m => m.Value,
Feet f => f.Value * 0.3048,
_ => throw new InvalidOperationException(),
};
}Union personalizzati con l’attributo [Union]La parola chiave union genera sempre uno struct. Se per motivi di identità, ereditarietà o layout di memoria serve un tipo reference, è possibile costruire un union personalizzato applicando direttamente l’attributo System.Runtime.CompilerServices.UnionAttribute e implementando l’interfaccia IUnion:

[System.Runtime.CompilerServices.Union]
public class Shape : System.Runtime.CompilerServices.IUnion
{
private readonly object? _value;
public Shape(Circle value) { _value = value; }
public Shape(Rectangle value) { _value = value; }
public object? Value => _value;
}Nella grande maggioranza dei casi, però, la sintassi union compatta copre già ogni esigenza pratica: l’approccio con attributo è pensato per scenari con requisiti specifici che lo struct generato non può soddisfare.

Come provarlo oggiI union type sono attualmente in preview. Per sperimentarli serve l’SDK .NET 11 Preview e questa configurazione nel file di progetto:

ConclusioniF# ha le discriminated union fin dalle origini, e la richiesta di un equivalente in C# (csharplang issue #113) è aperta da anni. Con l’arrivo dei union type, non ogni problema di modellazione richiede più una gerarchia di classi: per rappresentare “uno tra un insieme chiuso di tipi”, ora esiste un costrutto di linguaggio dedicato, con conversioni implicite, pattern matching esaustivo e un’ottima integrazione con i record esistenti. Per chi lavora ogni giorno con API che possono restituire risultati eterogenei, o con event sourcing e domain modeling, è una delle novità più concrete della prossima versione di C#.

Fonte: .NET Blog, C# language reference proposal: Unions e Maarten Balliauw.

#c #guide #tutorial #net

0

Caricamento...

0
1

Caricamento...

Imparare a programmare giocando

Volete imparare a programmare giocando? Oppure siete già in grado ma volete mettere alla prova le vostre conoscenze

Altro...

Imparare a programmare giocando

Volete imparare a programmare giocando? Oppure siete già in grado ma volete mettere alla prova le vostre conoscenze? Abbiamo quello che fa per voi!

https://blog.lealternative.net/2020/10/07/imparare-a-programmare-giocando/

Imparare a programmare giocando Imparare a programmare giocando

#c #coding #esempipratici #giocando #giocare #javascript #programmare #programmazione

2

Caricamento...

0
4

Caricamento...