Postupy: Kontrola obsahu sestavení pomocí metadataLoadContext

Rozhraní API reflexe v .NET ve výchozím nastavení umožňuje vývojářům kontrolovat obsah sestavení načtených do hlavního kontextu spuštění. Někdy ale není možné načíst sestavení do kontextu spuštění, například protože byl zkompilován pro jinou platformu nebo architekturu procesoru nebo je to referenční sestavení. Rozhraní System.Reflection.MetadataLoadContext API umožňuje načíst a zkontrolovat taková sestavení. Sestavení načtená do objektu MetadataLoadContext jsou považována pouze za metadata, to znamená, že můžete zkoumat typy v sestavení, ale nemůžete spustit žádný kód obsažený v něm. Na rozdíl od kontextu MetadataLoadContext hlavního spuštění automaticky nenačítá závislosti z aktuálního adresáře. Místo toho používá vlastní logiku MetadataAssemblyResolver vazby, kterou jí předaný předaný.

Požadavky

Chcete-li použít MetadataLoadContext, nainstalujte System.Reflexe Ion. Balíček NuGet MetadataLoadContext Podporuje se v libovolné cílové rozhraní .NET Standard 2.0, například .NET Core 2.0 nebo .NET Framework 4.6.1.

Vytvoření MetadataAssemblyResolver pro MetadataLoadContext

MetadataLoadContext Vytvoření vyžaduje poskytnutí instance objektu MetadataAssemblyResolver. Nejjednodušší způsob, jak poskytnout jeden je použít PathAssemblyResolver, který řeší sestavení z dané kolekce řetězců cesty sestavení. Tato kolekce by kromě sestavení, která chcete zkontrolovat přímo, měla obsahovat také všechny potřebné závislosti. Pokud chcete například přečíst vlastní atribut umístěný v externím sestavení, měli byste zahrnout toto sestavení nebo výjimku. Ve většině případů byste měli zahrnout alespoň základní sestavení, tj. sestavení obsahující předdefinované systémové typy, například System.Object. Následující kód ukazuje, jak vytvořit PathAssemblyResolver pomocí kolekce skládající se z kontrolovaného sestavení a základního sestavení aktuálního modulu runtime:

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

Pokud potřebujete přístup ke všem typům seznamů BCL, můžete do kolekce zahrnout všechna sestavení modulu runtime. Následující kód ukazuje, jak vytvořit PathAssemblyResolver pomocí kolekce sestávající z kontrolovaného sestavení a všech sestavení aktuálního modulu 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);

Vytvoření metadataLoadContext

Chcete-li vytvořit MetadataLoadContext, vyvolat jeho konstruktor MetadataLoadContext(MetadataAssemblyResolver, String), předejte dříve vytvořené MetadataAssemblyResolver jako první parametr a název základní sestavení jako druhý parametr. Můžete vynechat název základního sestavení, v takovém případě se konstruktor pokusí použít výchozí názvy: "mscorlib", "System.Runtime" nebo "netstandard".

Po vytvoření kontextu do něj můžete načíst sestavení pomocí metod, jako LoadFromAssemblyPathje . Na načtených sestaveních můžete použít všechna rozhraní API reflexe s výjimkou rozhraní API, která zahrnují provádění kódu. Tato GetCustomAttributes metoda zahrnuje provádění konstruktorů, takže místo toho použijte metodu GetCustomAttributesData , pokud potřebujete prozkoumat vlastní atributy v souboru MetadataLoadContext.

Následující ukázka kódu vytvoří MetadataLoadContext, načte sestavení do něj a výstupem atributů sestavení do konzoly:

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}");
        }
    }
}

Pokud potřebujete testovat typy MetadataLoadContext pro rovnost nebo přiřaditelnost, použijte pouze objekty typu načtené do tohoto kontextu. Kombinování MetadataLoadContext typů s typy modulu runtime se nepodporuje. Představte si například typ testedType v MetadataLoadContext. Pokud potřebujete otestovat, jestli je z něj možné přiřadit jiný typ, nepoužívejte kód jako typeof(MyType).IsAssignableFrom(testedType). Místo toho použijte kód podobný tomuto:

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)}");
}

Příklad

Úplný příklad kódu naleznete v části Kontrola obsahu sestavení pomocí ukázky MetadataLoadContext.

Viz také