Delen via


Procedure: Assembly-inhoud inspecteren met MetadataLoadContext

Met de reflectie-API in .NET kunnen ontwikkelaars standaard de inhoud van assembly's controleren die in de hoofdcontext van de uitvoering zijn geladen. Soms is het echter niet mogelijk om een assembly in de uitvoeringscontext te laden, bijvoorbeeld omdat deze is gecompileerd voor een ander platform of processorarchitectuur, of een referentieassembly. Met de System.Reflection.MetadataLoadContext API kunt u dergelijke assembly's laden en inspecteren. Assembly's die in de MetadataLoadContext assembly worden geladen, worden alleen behandeld als metagegevens, dat wil gezegd, u kunt typen in de assembly onderzoeken, maar u kunt geen code in de assembly uitvoeren. In tegenstelling tot de hoofdcontext voor de uitvoering worden MetadataLoadContext afhankelijkheden van de huidige map niet automatisch geladen. In plaats daarvan wordt de aangepaste bindingslogica gebruikt die door de MetadataAssemblyResolver doorgegeven map wordt geleverd.

Vereisten

Installeer het NuGet-pakket System.Reflection.MetadataLoadContext om te gebruikenMetadataLoadContext. Het wordt ondersteund voor elk .NET Standard 2.0-compatibel doelframework, bijvoorbeeld .NET Core 2.0 of .NET Framework 4.6.1.

MetadataAssemblyResolver maken voor MetadataLoadContext

Voor het maken van de MetadataLoadContext configuratie is het vereist dat het exemplaar van de MetadataAssemblyResolver. De eenvoudigste manier om er een te bieden, is het gebruik van de PathAssemblyResolver, waarmee assembly's worden omgezet uit de opgegeven verzameling assemblypadtekenreeksen. Deze verzameling, naast assembly's die u rechtstreeks wilt inspecteren, moet ook alle benodigde afhankelijkheden bevatten. Als u bijvoorbeeld het aangepaste kenmerk in een externe assembly wilt lezen, moet u die assembly opnemen of een uitzondering genereren. In de meeste gevallen moet u ten minste de kernassembly opnemen, dat wil gezegd, de assembly met ingebouwde systeemtypen, zoals System.Object. De volgende code laat zien hoe u de PathAssemblyResolver verzameling maakt die bestaat uit de geïnspecteerd assembly en de kernassembly van de huidige runtime:

var resolver = new PathAssemblyResolver(new string[] { "ExampleAssembly.dll", typeof(object).Assembly.Location });

Als u toegang nodig hebt tot alle BCL-typen, kunt u alle runtime-assembly's in de verzameling opnemen. De volgende code laat zien hoe u de PathAssemblyResolver verzameling maakt die bestaat uit de geïnspecteerde assembly en alle assembly's van de huidige runtime:

// Get the array of runtime assemblies.
string[] runtimeAssemblies = Directory.GetFiles(RuntimeEnvironment.GetRuntimeDirectory(), "*.dll");

// Create the list of assembly paths consisting of runtime assemblies and the inspected assembly.
var paths = new List<string>(runtimeAssemblies);
paths.Add("ExampleAssembly.dll");

// Create PathAssemblyResolver that can resolve assemblies using the created list.
var resolver = new PathAssemblyResolver(paths);

MetadataLoadContext maken

Als u de constructor wilt maken, roept u de MetadataLoadContextconstructor MetadataLoadContext(MetadataAssemblyResolver, String)aan en geeft u de eerder gemaakte MetadataAssemblyResolver als de eerste parameter en de naam van de kernassembly door als de tweede parameter. U kunt de naam van de kernassembly weglaten. In dat geval probeert de constructor standaardnamen te gebruiken: 'mscorlib', 'System.Runtime' of 'netstandard'.

Nadat u de context hebt gemaakt, kunt u er assembly's in laden met behulp van methoden zoals LoadFromAssemblyPath. U kunt alle weerspiegelings-API's gebruiken voor geladen assembly's, met uitzondering van assembly's die betrekking hebben op het uitvoeren van code. De GetCustomAttributes methode omvat de uitvoering van constructors, dus gebruik in plaats daarvan de GetCustomAttributesData methode wanneer u aangepaste kenmerken in de MetadataLoadContext.

Het volgende codevoorbeeld maakt MetadataLoadContext, laadt de assembly erin en voert assemblykenmerken uit in de console:

var mlc = new MetadataLoadContext(resolver);

using (mlc)
{
    // Load assembly into MetadataLoadContext.
    Assembly assembly = mlc.LoadFromAssemblyPath("ExampleAssembly.dll");
    AssemblyName name = assembly.GetName();

    // Print assembly attribute information.
    Console.WriteLine($"{name.Name} has following attributes: ");

    foreach (CustomAttributeData attr in assembly.GetCustomAttributesData())
    {
        try
        {
            Console.WriteLine(attr.AttributeType);
        }
        catch (FileNotFoundException ex)
        {
            // We are missing the required dependency assembly.
            Console.WriteLine($"Error while getting attribute type: {ex.Message}");
        }
    }
}

Als u typen MetadataLoadContext wilt testen voor gelijkheid of toewijsbaarheid, gebruikt u alleen typeobjecten die in die context zijn geladen. Het combineren van MetadataLoadContext typen met runtimetypen wordt niet ondersteund. Denk bijvoorbeeld aan een type testedType in MetadataLoadContext. Als u wilt testen of een ander type kan worden toegewezen, gebruikt u geen code zoals typeof(MyType).IsAssignableFrom(testedType). Gebruik in plaats daarvan code als volgt:

Assembly matchAssembly = mlc.LoadFromAssemblyPath(typeof(MyType).Assembly.Location);
Type matchType = assembly.GetType(typeof(MyType).FullName!)!;

if (matchType.IsAssignableFrom(testedType))
{
    Console.WriteLine($"{nameof(matchType)} is assignable from {nameof(testedType)}");
}

Opmerking

Zie de assembly-inhoud inspecteren met behulp van het voorbeeld MetadataLoadContext voor een volledig codevoorbeeld.

Zie ook