Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Por padrão, a API de reflexão no .NET permite que os desenvolvedores inspecionem o conteúdo dos assemblies carregados no contexto de execução principal. No entanto, às vezes não é possível carregar um assembly no contexto de execução, por exemplo, porque ele foi compilado para outra arquitetura de plataforma ou processador ou um assembly de referência. A System.Reflection.MetadataLoadContext API permite que você carregue e inspecione esses assemblies. Os assemblies carregados no MetadataLoadContext são tratados apenas como metadados, ou seja, você pode examinar tipos no assembly, mas não pode executar nenhum código contido nele. Ao contrário do contexto de execução principal, o MetadataLoadContext não carrega dependências automaticamente do diretório atual; em vez disso, ele usa a lógica de associação personalizada fornecida pelo MetadataAssemblyResolver.
Pré-requisitos
Para usar MetadataLoadContext, instale o pacote NuGet System.Reflection.MetadataLoadContext . Ele tem suporte em qualquer estrutura de destino compatível com o .NET Standard 2.0, por exemplo, .NET Core 2.0 ou .NET Framework 4.6.1.
Criar MetadataAssemblyResolver para MetadataLoadContext
Criar o MetadataLoadContext requer fornecer a instância do MetadataAssemblyResolver. A maneira mais simples de fornecer um é usar o PathAssemblyResolver, que resolve assemblies a partir de uma coleção determinada de caminhos de assembly. Essa coleção, além de assemblies que você deseja inspecionar diretamente, também deve incluir todas as dependências necessárias. Por exemplo, para ler o atributo personalizado localizado em um assembly externo, você deve incluir esse assembly, caso contrário, uma exceção será lançada. Na maioria das vezes, você deve incluir pelo menos o assembly central, isto é, o assembly que contém tipos de sistema embutidos, como System.Object. O código a seguir mostra como criar o PathAssemblyResolver usando a coleção que consiste no assembly inspecionado e no assembly central do runtime vigente.
var resolver = new PathAssemblyResolver(new string[] { "ExampleAssembly.dll", typeof(object).Assembly.Location });
Se você precisar de acesso a todos os tipos de BCL, poderá incluir todos os assemblies de runtime na coleção. O código a seguir mostra como criar o PathAssemblyResolver utilizando a coleção que consiste no assembly inspecionado e em todos os assemblies do tempo de execução atual.
// 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);
Criar MetadataLoadContext
Para criar o MetadataLoadContext, invoque o construtor MetadataLoadContext(MetadataAssemblyResolver, String), passando o MetadataAssemblyResolver previamente criado como o primeiro parâmetro e o nome do assembly central como o segundo parâmetro. Você pode omitir o nome do assembly principal, caso em que o construtor tentará usar nomes padrão: "mscorlib", "System.Runtime" ou "netstandard".
Depois de criar o contexto, você pode carregar assemblies nele usando métodos como LoadFromAssemblyPath. Você pode usar todas as APIs de reflexão nos assemblies carregados, exceto aquelas que envolvem a execução de código. O GetCustomAttributes método envolve a execução de construtores, portanto, use o GetCustomAttributesData método quando precisar examinar atributos personalizados no MetadataLoadContext.
O exemplo de código a seguir cria MetadataLoadContext, carrega o assembly nele e exibe atributos de assembly no 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}");
}
}
}
Se você precisar testar tipos MetadataLoadContext para igualdade ou atribuibilidade, use apenas objetos de tipo carregados nesse contexto. Não há suporte para a combinação de MetadataLoadContext tipos com tipos de runtime. Por exemplo, considere um tipo testedType em MetadataLoadContext. Se você precisar testar se outro tipo é atribuível a partir dele, não use código como typeof(MyType).IsAssignableFrom(testedType). Em vez disso, use um código como este:
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)}");
}
Example
Para obter um exemplo de código completo, consulte o exemplo Inspecionar conteúdo do assembly usando MetadataLoadContext.