Generazione e compilazione dinamica

Durante i miei esperimenti di generazione e compilazione dinamica di codice mi sto imbattendo in quella che non stenterei a definire una stranezza.
Genero al volo una classe che estende una classe base (definita nella libreria che genera il codice) e si riferisce ad un particolare tipo che varia di volta in volta e si trova probabilmente in un'altra libreria.
Al momento della generazione imposto tutti i riferimenti e le opzioni:

Dim provider As Microsoft.VisualBasic.VBCodeProvider
Dim compiler As System.CodeDom.Compiler.ICodeCompiler
Dim results As System.CodeDom.Compiler.CompilerResults
Dim cp As New System.CodeDom.Compiler.CompilerParameters
cp.ReferencedAssemblies.Add("System.dll")
cp.ReferencedAssemblies.Add("System.Data.dll")

Presto particolare attenzione a riferire gli assembly (ed ogni eventuale loro dipendenza) che non si trovano nella GAC specificandone il loro percorso COMPLETO. Ed eccomi al punto saliente

cp.GenerateInMemory = True

Ovvero comunico con questa opzione al compilatore che non desidero che l'assembly venga scritto su disco, ma che rimanga in memoria.
La generazione va a buon fine (sebbene l'assembly venga scritto su disco nella cartella temporanea) e non ci sono errori apparenti fino a quando uno dei riferimenti non si trova né nella GAC, né nella cartella dell'applicazione (é stato caricato dinamicamente da una cartella di plugin ad esempio). In tal caso quando si cerca di usare il tipo generato viene sollevata un eccezione che specifica l'impossibilità di trovare l'assembly di questo riferimento. Ho provato anche ad impostare la proprietà: cp.CompilerOptions = "libpath:""cartella della mia DLL""", ma continua a non funzionare finché non imposto:
cp.GenerateInMemory = False
E sì che alla fine dei conti il risultato é apparentemente lo stesso in quanto l'assembly viene comunque generato nella cartella temporanea (salvo diversa indicazione). Misteri di .NET!

UPDATE: spiego meglio viste le numerose domande.
A1 = Assembly del programma principale, contiene una classe PlugIn. Il programma ricerca in una particolare cartella assembly che contengano una classe che estende PlugIn e li carica

A2 = Assembly che contiene la classe MyPlugIn che eredita da A1.PlugIn. Dipende da A3

A3 = Assembly che contiene la classe UtilityBase (mustinherit). UtilityBase ha un metodo Shared che riceve un Type, genera del codice VB ottimizzato per tale tipo, compila questo codice in un assembly (chiamato AD)

Finché A1 ha un riferimento ad A2 (e questi si trova quindi nella stessa cartella di A1) FUNZIONA TUTTO. Il problema sorge quanto A1 carica A2 dinamicamente da un altro percorso in tal caso l'assembly generato AD da un errore in esecuzione (sì, non in compilazione) di tipo TypeLoadException: "impossibile trovare l'assembly A2". Per ovviare a questo problema basta impostare fra le opzioni di compilazione per AD GenerateInMemory = False. In ogni caso verrebbe generato un file temporaneo per l'assembly, quindi NON capisco proprio il perché di questo comportamento. Comunque, se aveste mai lo stesso problema... ;-)

Print | posted on martedì 13 settembre 2005 18:46

Comments on this post

# Re: Generazione e compilazione dinamica

Requesting Gravatar...
Se ne vieni a capo fammelo sapere... potrebbe venire utile...
Left by Lorenzo Melato on set 13, 2005 4:48

# re: Generazione e compilazione dinamica

Requesting Gravatar...
Scusa per il feed a più trance... qsto, http://www.codeproject.com/csharp/cscompiler.asp, ti potrebbe interessare. Contiene esempio di aggiunta di referenze... se ci sono acnora problemi ci spostiamo sul forum ;-p
Left by M.rkino on set 13, 2005 6:06

# re: Generazione e compilazione dinamica

Requesting Gravatar...
Macché scusa, grazie M.rkino! :-D
Non mi si apre il link... Riproverò più tardi (o domani), ma credo di averlo già visto...
Il problema non si presenta in condizioni normali, ma solo quando una delle dipendenze é stata caricata dinamicamente da un file che non si trova nella stessa cartella dell'eseguibile.
Con caricato dinamicamente intendo System.Reflection.Assembly.LoadFromFile()
...ho messo a ferro e fuoco MSDN, blog, google, newsgroup, ma non ho trovato niente di così specifico...
Left by Michele Bernardi on set 13, 2005 6:27
Comments have been closed on this topic.