Generazione dinamica di codice .NET 2.0 Ricci Gian Maria [email protected] MarCamp : 24 febbraio 2007 Generazione dinamica di codice Codice che genera codice Un programma genera codice a run-time durante la sua esecuzione Un programma così strutturato deve necessariamente essere strutturato per essere estensibile. Supporto nativo dell’ambiente alla generazione ed al caricamento dinamico di codice Come strutturare il progetto Non si conosce a priori il “tipo” di dato su cui si lavora Creare interfacce come punti di collegamento per l’estendibilità Utilizzare classi base con metodi virtuali per incapsulare le funzionalità base Accedere ai nuovi tipi con indentificazione runtime (reflection) Strutturare le modalità di caricamento Single AppDomain Multi AppDomain Comunicare per interfacce Core Interfaccia Tipo dinamico Tipo dinamico Tipo dinamico Comunicare per classi base Core Base Tipo dinamico Tipo dinamico Tipo dinamico Comunicare per reflection Core Tipo dinamico Informazioni sul tipo Invocazione dinamica Perchè generare codice dinamicamente Creazione classi proxy di classi reali Intercettare le chiamate ai metodi per trovare metriche di codice Aspect Oriented Programming Necessità specifiche es: NHibernate lazy load Mock object Creare oggetti che simulano classi reali Generazione runtime proxy a servizi E’ affascinante Generazione in .NET 2.0 Una prima possibilità consiste nel generare dinamicamente un file di testo contenente codice C#, VB, etc.. e poi chiamare direttamente il compilatore generando così una dll che può essere caricata runtime. Vantaggi Estrema semplicità Svantaggi Possibilità di errore nella generazione di file Scarso controllo degli errori Generazione tramite compilatore Core C# sc.exe dll Utilizzare il CodeDom Una possibilità migliore consiste nella generazione di codice tramite le classi contenute nel namespace CodeDom. Grazie a questa libreria è possibile controllare in dettaglio come verranno generati i tipi dinamici. Dim cg As ICodeGenerator = _ New CSharpCodeProvider().CreateGenerator() Vantaggi Controllo accurato sul codice generato Impossibiltà di generazione di errori di sintassi Utile per generatori di codice Svantaggi Generazione di codice complessa Generazione tramite CodeDom Core CodeDom dll Reflection.Emit() L’ultima possibilità offerta dal .NET 2.0 è la generazione di codice dinamica tramite Reflection.Emit(). Sostanzialmente tramite Emit si possono ottenere gli stessi risultati che si possono ottenere tramite CodeDom, ma si hanno dei vantaggi. Codice più lineare e snello Iniezione diretta dei tipi in un AppDomain senza passare per una classe compilatore Estrema facilità di utilizzo a patto di conoscere MSIL Possibilità di generare nuovi tipi in ogni momento, l’assembly generato dinamicamente non è chiuso. Generazione tramite Reflectio.Emit() Core Emit Reflection.Emit() L’ultima possibilità offerta dal .NET 2.0 è la generazione di codice dinamica tramite Reflection.Emit(). Vantaggi Codice più lineare e snello Iniezione diretta dei tipi in un AppDomain senza passare per la compilazione Maggiore performance Possibilità di generare nuovi tipi in ogni momento Svantaggi Richiesta buona conoscenza di MSIL Abstract View Domande?