Assembly.GetTypes()

Ho tribulato non poco su un "passaggio" che alla fin fine (dopo averlo risolto!) si è rivelato tutto sommato banale: dovevo recuperare tramite Reflection i tipi contenuti in un assembly ma alcuni di questi tipacci derivavano da tipi base contenuti in un altro assembly ovviamente non referenziato.

Sono partito sparato (forse è anche per questo che ho continuato a tirare testate) col metodo GetReferencedAssemblies() della classe System.Reflection.Assembly e da lì sono riuscito ovviamente a recuperare i vari tipi di base contenuti, ma non riuscivo a capire come "referenziare" quegli assemblies per renderli disponibile al GetTypes() dell'assembly iniziale.

Sono passato per AppDomain.CurrentDomain.Load(), ma al runtime non gliene poteva fregare di meno; ho anche guardato l'evento AppDomain.CurrentDomain.AssemblyResolve, ma nel ResolveEventArgs ho trovato solo il membro args.Name : String ed ho chiuso baracca e burattini.

Dieci minuti dopo il dubbio: vado a rivedere quell'evento e... mi accorgo che ha un valore di ritorno!

Sono una voce tutt'altro che autoritaria in materia, ma se non erro le guidelines dicono che i Delegates per gli eventi non dovrebbero avere un tipo di ritorno ma piuttosto includere eventuali "modifiche" come membri dell'EventArgs specifico!

Comunque è stato sufficiente inserire un (bruttissimo) pezzo di codice come questo:

Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    MessageBox.Show(string.Format("Could not load file or assembly {0}.", args.Name), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button1);


    using (OpenFileDialog missingReferenceDlg = new OpenFileDialog())
    {
        missingReferenceDlg.Multiselect = false;
        missingReferenceDlg.Title = args.Name;


        if (missingReferenceDlg.ShowDialog() == DialogResult.Cancel)
            return null;

        try
        {
            return Assembly.LoadFile(missingReferenceDlg.FileName);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString(), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
            return null;
        }
    }
}

ed il tutto è filato via liscio, con tante tante perplessità sul "senso unico" imposto dall'implementazione di questa funzionalità del Framework.

Il problema è che il Framework .NET (quasi sempre) è talmente pulito che mi viene sempre da pensare ad un mio errore piuttosto che ad un comportamento "inusuale".

Print | posted @ lunedì 19 marzo 2007 19:34

Comments on this entry:

Gravatar # re: Assembly.GetTypes()
by Federico at 20/03/2007 11:46

Ciao Mario, il caso che hai spiegato è molto interessante e istruttivo, complimenti. Non avevo mai riflettuto sul fatto che un delegate può avere un valore di ritorno!
Gravatar # re: Assembly.GetTypes()
by Mario Duzioni at 20/03/2007 12:01

Grazie, mi fai arrossire! :-)

Il delegate in effetti è solo un puntatore a funzione e la funzione può avere una firma qualsiasi.

Nel caso degli eventi però se non erro sarebbe meglio non utilizzare i valori di ritorno ed inserirli nella classe EventArgs specifica. Nel caso specifico mi sarei aspettato nella classe ResolveEventArgs una property "ResolvedAssembly" da settare, tipo:

args.ResolvedAssembly = myAssembly;

P.S. Un ultima considerazione: di solito il paramentro di EventArgs si chiama e (es e.Cancel), qui l'hanno chiamato args!
Comments have been closed on this topic.