Common Language Runtime (CLR o CLI) | ||
I tre componenti principali di .NET Framework Common Language Runtime/Infrastructure (CLR/CLI) CLS - Common Language Specification CIL - Common Intermediate Language VES - Virtual Execution System |
ECMA fa riferimento al Common Language Runtime (CLR nella documentazione Microsoft) con la sigla di CLI, Common Language Infrasturcture. Il Common Language Runtime rappresenta un motore di esecuzione ad elevate prestazioni. Il codice cui il runtime si riferisce e la cui esecuzione è gestita da esso viene detto codice gestito (managed code). La responsabilità per attività quali la creazione di oggetti, l'esecuzione di chiamate a metodi e così via, è demandata al Common Language Runtime che consente di fornire servizi aggiuntivi al codice in esecuzione.
A dispetto del suo nome, il Common Language Runtime riveste in realtà un ruolo tanto nella fase di sviluppo di componenti quanto nella fase di esecuzione. Mentre la componente è in esecuzione, il runtime fornisce servizi quali la gestione della memoria (inclusa la garbage collection), la gestione di processi e thread, il potenziamento della sicurezza e si preoccupa di soddisfare le eventuali dipendenze da altre componenti. Durante la fase di sviluppo, il ruolo del runtime cambia leggermente. Grazie agli automatismi introdotti (ad esempio nella gestione della memoria), il runtime rende la vita dello sviluppatore molto più semplice. In particolare, caratteristiche quali la gestione del ciclo di vita, una nomenclatura forte dei tipi, la gestione delle eccezioni tra linguaggi, la gestione degli eventi basati sui delegate, il binding dinamico e la reflection, riducono considerevolmente la quantità di codice che occorre scrivere per realizzare codice a componenti riutilizzabili. I runtime non rappresentano una novità per i linguaggi: molti linguaggi di programmazione possiedono un runtime. Visual Basic, ad esempio, possiede forse il runtime più famoso (il VBRUN), ma anche Visual C++ ne possiede uno (MSVCRT) e così pure Visual FoxPro, Jscript, SmallTalk, Perl, Python, Haskell e Java. Il ruolo critico del Common Language Runtime, e ciò che realmente lo contraddistingue, è il fatto che fornisce un ambiente di runtime unificato comune a tutti i linguaggi di programmazione. Le caratteristiche fondamentali del runtime includono un sistema comune di tipi che consente l'integrazione tra linguaggi (oggetti C# possono ereditare classi C++, ad esempio) , componenti autodescrittive, un deployment più semplice ed un miglior controllo dei conflitti di versione ed infine, servizi di sicurezza integrati. Al momento il .NET framework supporto tre linguaggi compilati: VB.NET, Visual C++, e C#. Questi linguaggi danno come risultato un codice eseguibile dal runtime, al quale deve essere ovviamente conforme. Questo tipo di codice aderente alle regole e alle strutture dati offerte dal CLR è chiamato managed code (codice gestito). Codice macchina insicuro (perché scavalca il runtime) può essere generato dai compilatori, e in questo caso si parla di unmanaged code (codice non gestito). L'accesso alle Garbage Collection sono possibili solo attraverso il managed code. Il codice gestito ha accesso al Common Language Runtime attraverso il quale può avvantaggiarsi delle caratteristiche della piattaforma (integrazione multi linguaggio, gestione delle eccezioni, sicurezza, gestione delle versioni, ecc.). In breve il CLR fornisce servizi al codice gestito.
I compilatori emettono metadata (metadati) che descrivono i tipi i membri e i riferimenti nel codice, e che vengono memorizzati insieme al codice: ogni blocco di codice eseguibile del runtime contiene metadati. Il .NET Framework consente la creazione di componenti autodescrittive che semplificano lo sviluppo e la distribuzione e migliorano l'affidabilità del sistema. L'autodescrizione viene ottenuta tramite questi metadati - informazioni contenute nel codice binario che integrano il codice eseguibile, forniscono dettagli sulle dipendenze, sulle versioni e così via. I metadati vengono pacchettizzati assieme alla componente che descrivono ed il risultato è appunto una componente autodescrittiva. Un vantaggio fondamentale delle componenti autodescrittive risiede nel fatto che non occorrono ulteriori file per utilizzarle. Ciò differisce dalla modalità attuale di sviluppo di applicazioni, che richiede un file di intestazione separato per la definizione delle classi, file distinti per il linguaggio di descrizione dell'interfaccia (IDL), per le type library, per i proxy e per gli stub. Dal momento che i metadati vengono generati dal codice sorgente durante il processo di compilazione e memorizzati con il codice eseguibile, sono sempre in sincronia con l'eseguibile. Dal momento che ogni applicazione contiene una descrizione completa di se stessa, il runtime può generare dinamicamente una cache di informazioni sulle componenti installate in un sistema. Se, ad esempio, tale cache viene danneggiata, il runtime può ricostruirla in maniera trasparente per l'utente. Oltre a risolvere problemi legati allo sviluppo, l'autodescrizione consente di individuare le componenti senza ricorrere al Registry di Windows. Il vantaggio in questo caso è la possibilità di effettuare un deployment che non richiede modifiche del sistema. Il CLR come la Java Virtual Machine fornisce una garbage collection automatica per il managed code chiamata managed data. Contrariamente alla macchina virtuale Java , il CLR fornisce un meccanismo per disabilitare la garbage collection automatica chiamato unmanaged data, nella quale il programmatore è responsabile per la garbage collection. Il CLR è stato progettato per facilitare la integrazione fra i linguaggi; due tipi di integrazione sono possibili: strettamente accoppiata (tightly coupled) o debolmente accoppiata (loosely coupled) chiamata anche remoting. Il metodo di chiamata interlinguaggio strettamente accoppiato è ottenuto attraverso il CLR, questo assume che i due linguaggi che comunicano siano entrambi aderenti all'architettura .NET come VC++, VB.NET o C#, o almeno aderenti a COM. I programmi C# possono comunicare con i programmi Java usando come ponte ActiveX Java Bean, assumendo che entrambi siano residenti sullo stesso computer. L'integrazione debolmente accoppiata (remoting) è indicata quando due programmi che devono interagire, scritti in linguaggi differenti, risiedono su piattaforme ospitanti diversi sistemi operativi, come un client C# su Windows in comunicazione con codice Java residente su un server Solaris. Questa integrazione ottenuta mediante un protocollo chiamato Simple Object Access Protocol (SOAP), basato su XML del quale è già stato fornito qualche accenno nel primo capitolo di questo tutorial. SOAP ha un layer di trasporto indipendente con un contenuto formattato XML; al momento sono disponibili implementazioni del trasporto HTTP e SMTP da Microsoft e Apache.org per il framework .NET e per la piattaforma Java rispettivamente. Un'altra interessante caratteristica introdotta è la riduzione dalla dipendenza dal registro di Windows. Le informazioni di registrazione non sono più memorizzate nel registro di sistema, ma all'interno dei metadati. Questo dovrebbe facilitare la distribuzione dei componenti; in effetti Microsoft parla di distribuzione "No-touch" che consiste nel copiare semplicemente un file su un computer di destinazione e di eseguirlo senza bisogno di registrarlo. Oltre all'eliminazione della dipendenza dal Registry, il .NET Framework include ulteriori miglioramenti nella distribuzione che eliminano di fatto i problemi legati ai conflitti tra DLL - il fenomeno per cui una libreria condivisa va fuori sincronia con le applicazioni che la utilizzano. La distribuzione "side-by-side" consente ora a più versioni differenti della stessa libreria di coesistere senza conflitti. Il .NET Framework include un sistema di nomenclatura interna estremamente potente che rende praticamente impossibile confondere due librerie distinte che hanno lo stesso nome. Se una nuova applicazione sovrascrive una libreria condivisa, un'applicazione esistente che non è in grado di utilizzare la nuova libreria può, in realtà, autoripararsi. Quando l'applicazione esistente viene lanciata nuovamente, effettua una verifica dei propri file condivisi; se trova che uno di questi è stato modificato e risulta, pertanto, incompatibile, può chiedere al runtime di recuperarne una versione sicuramente funzionante. Grazie al sistema di sicurezza, il runtime può agire in modo sicuro e l'applicazione è di conseguenza in grado di ripararsi da sola.
Il Common Language Runtime è composto da cinque componenti che sono:
|