Search code examples
c#reflectionreferencereflector

C# reflection and finding all references


Given a DLL file, I'd like to be able to find all the calls to a method within that DLL file. How can I do this?

Essentially, how can I do programmatically what Visual Studio already does?

I don't want to use a tool like .NET Reflector to do this, but reflection is fine and probably necessary.


Solution

  • To find out where a method MyClass.Foo() is used, you have to analyse all classes of all assemblies that have a reference to the assembly that contains MyClass. I wrote a simple proof of concept of how this code can look like. In my example I used this library (it's just a single .cs file) written by Jb Evain:

    I wrote a little test class to analyse:

    public class TestClass
    {
        public void Test()
        {
            Console.WriteLine("Test");
            Console.Write(10);
            DateTime date = DateTime.Now;
            Console.WriteLine(date);
        }
    }
    

    And I wrote this code to print out all the methods used within TestClass.Test():

    MethodBase methodBase = typeof(TestClass).GetMethod("Test");
    var instructions = MethodBodyReader.GetInstructions(methodBase);
    
    foreach (Instruction instruction in instructions)
    {
        MethodInfo methodInfo = instruction.Operand as MethodInfo;
    
        if(methodInfo != null)
        {
            Type type = methodInfo.DeclaringType;
            ParameterInfo[] parameters = methodInfo.GetParameters();
    
            Console.WriteLine("{0}.{1}({2});",
                type.FullName,
                methodInfo.Name,
                String.Join(", ", parameters.Select(p => p.ParameterType.FullName + " " + p.Name).ToArray())
            );
        }
    }
    

    It gave me the following output:

    System.Console.WriteLine(System.String value);
    System.Console.Write(System.Int32 value);
    System.DateTime.get_Now();
    System.Console.WriteLine(System.Object value);
    

    This example is obviously far from complete, because it doesn't handle ref and out parameters, and it doesn't handle generic arguments. I am sure that forgot about other details as well. It just shows that it can be done.