jeudi 17 novembre 2022

How to find all classes that implement a specific interface using System.Reflection.Metadata

I'm trying to figure out whether I can reliably identify .NET assemblies that contain classes that implement a specific interface. The catch here is that I cannot load assemblies using Reflection because that requires resolving all references of the assembly to be loaded and that is just not possible in my situation.

This is why I attempt to do so using the NuGet package System.Reflection.Metadata because that approach does not seem to require loading referenced assemblies. However, I'm stuck with completing the code so that the interface in question is found. Here's what I have:

namespace ReflectionMetadataTest
{
   using System;
   using System.IO;
   using System.Reflection.Metadata;
   using System.Reflection.PortableExecutable;

   public static class Program
   {
      static int Main(string[] args)
      {
         if (args.Length < 1)
         {
            Console.Error.WriteLine("Please specify a single file path.");
            return 1;
         }

         string filePath = new FileInfo(args[0]).FullName;

         using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
         {
            using (var peReader = new PEReader(fileStream))
            {
               if (!peReader.HasMetadata)
               {
                  return 2;
               }

               MetadataReader metadataReader = peReader.GetMetadataReader();

               foreach (var typeDefinitionHandle in metadataReader.TypeDefinitions)
               {
                  var typeDefinition = metadataReader.GetTypeDefinition(typeDefinitionHandle);
                  var interfaceHandles = typeDefinition.GetInterfaceImplementations();

                  foreach (var interfaceHandle in interfaceHandles)
                  {
                     var interfaceImplementation = metadataReader.GetInterfaceImplementation(interfaceHandle);
                     var whateverThatIs = interfaceImplementation.Interface;

                     // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                     // TODO: How would I find the fully qualified name of the the interface so that I can compare with the name I'm looking for?
                     // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                  }
               }

               return 0;
            }
         }
      }
   }
}

How would I resolve whateverThatIs to an actual type of fully qualified name so that I can then compare it with the type/name of the interface that I'm looking for?





Aucun commentaire:

Enregistrer un commentaire