La classe Assembly prevede il metodo GetReferencedAssembly() per recuperare l’elenco degli AssemblyName ralativi agli assembly referenziati da un determinato assembly.
Il problema è che se abbiamo una struttura con più dll referenziate a catena, il metodo restituisce solo il primo livello della stessa catena.
Supponiamo di avere la seguente struttura:
ovvero il progetto AssemblyExtension referenzia la dll AssemblyExtensionLIB1 che, a sua volta, referenzia la AssemblyExtensionLIB2.
In questo caso, il metodo GetReferencedAssembly(), applicato sull’assembly AssemblyExtension, restituisce il seguente elenco:
Come si può vedere non c’è traccia della AssemblyExtensionLIB2.
Il seguente metodo di estensione provvede ad eseguire un algoritmo ricorsivo per recuperare una lista di AssemblyName contenente tutte le reference dell’assembly:
- Imports System.Runtime.CompilerServices
- Imports System.Reflection
- Module AssemblyExtension
- <Extension()> _
- Public Sub GetAllReferenceAssemblies(ByVal sourceAssembly As Assembly,
- ByVal allowGacAssembly As Boolean,
- ByVal list As ICollection(Of AssemblyName))
- If sourceAssembly Is Nothing Then Throw New ArgumentNullException("Source Assembly")
- If list Is Nothing Then Throw New ArgumentNullException("Destination List")
- list.Add(sourceAssembly.GetName())
- If allowGacAssembly OrElse Not sourceAssembly.GlobalAssemblyCache Then
- Dim assemblies = sourceAssembly.GetReferencedAssemblies()
- For Each assemblyName In assemblies
- Dim query = From a In list _
- Where a.FullName = assemblyName.FullName _
- Select a
- If query.Count = 0 Then
- Dim assembly As Assembly = assembly.Load(assemblyName.FullName)
- assembly.GetAllReferenceAssemblies(allowGacAssembly, list)
- End If
- Next
- End If
- End Sub
- End Module
Il metodo di estensione è applicabile su un qualsiasi assembli e i parametri sono:
- allowGacAssembly: indica se eseguire la ricerca delle referenze all’interno delle dll contenute nella GAC;
- list: è la lista che conterrà gli AssemblyName risultato della ricerca.
Se nel progetto precedente scriviamo:
- Dim list = New List(Of AssemblyName)
- Assembly.GetEntryAssembly().GetAllReferenceAssemblies(True, list)
Otteniamo:
Mentre se impostiamo allowGacAssembly=false:
Attenzione: il metodo GetReferencedAssembly restituisce gli assembly effettivamente referenziati (cioè quelli per i quali c’è almeno un tipo utilizzato) e non quelli inseriti nelle referenze di Visual Studio.
Commenti