Published Saturday, March 03, 2007 3:45 AM by mtaulty

Finding Extension Methods

I was struggling to find the Field extension method in the March "Orcas" CTP and so I wrote a bit of code that would print out extension methods from assemblies it loads. It's very basic but I'll share here in case anyone wants it or takes the idea and makes it proper (this would be a great Reflector feature and I'm sure it'll crop up at a later point).

Note - assumptions are probably wrong but it did help me find that DataRow.Field as an extension now seems to be in System.Data.Entity.dll. I still couldn't find a ToQueryable or a AsQueryable for DataTable or DataSet so I'm not sure what's happened there although there does still seem to be an AsEnumerable for DataTable. This comes from System.Data.DataTableExtensions.

Note - it would be nice to re-write this to use LINQ rather than "for each" but I am short of time at the time of posting :-)

using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;

class Program
{
 static void Main(string[] args)
 {
  foreach (string s in Directory.GetFiles(".", "*.dll"))
  {
   try
   {
    Assembly a = Assembly.LoadFrom(s);
    bool dumpedAssembly = false;

    foreach (Type t in a.GetExportedTypes())
    {
     bool dumpedClass = false;

     if (t.IsClass)
     {
      foreach (MethodInfo mi in t.GetMethods(
       BindingFlags.Public | BindingFlags.Static))
      {
       ExtensionAttribute[] extAttrs =
        (ExtensionAttribute[])mi.GetCustomAttributes(
         typeof(ExtensionAttribute), false);

       if ((extAttrs != null) && (extAttrs.Length > 0))
       {
        if (!dumpedAssembly)
        {
         DumpAssembly(s);
         dumpedAssembly = true;
        }
        if (!dumpedClass)
        {
         DumpClass(t);
         dumpedClass = true;
        }
        DumpMethod(mi);
       }
      }
     }
    }
   }
   catch (Exception ex)
   {
    DumpError(s, ex);
   }
  }
 }

 private static void DumpError(string fileName, Exception ex)
 {
  Console.ForegroundColor = ConsoleColor.Red;

  Console.WriteLine("ERROR for assembly {0}, [{1}]",
   fileName, ex.Message);

  Console.ResetColor(); 
 }
 private static void DumpAssembly(string fileName)
 {
  PrintColour(ConsoleColor.White, "ASSEMBLY [{0}]", 
   fileName);
 }
 private static void DumpClass(Type classType)
 {
  PrintColour(ConsoleColor.Yellow, "\tEXTENSION CLASS [{0}]", 
   classType.FullName);
 }
 private static void PrintColour(ConsoleColor color, string message, 
  params object[] args)
 {
  Console.ForegroundColor = color;
  Console.WriteLine(message, args);
  Console.ResetColor();
 }
 private static void DumpMethod(MethodInfo mi)
 {
  ParameterInfo[] pi = mi.GetParameters();

  PrintColour(ConsoleColor.Green,
   "\tMethod [{0}] extends type [{1}]", mi.Name,
   pi[0].ParameterType.Name);
 }
}

# Interesting Finds: March 4, 2007 @ Sunday, March 04, 2007 7:21 AM

Jason Haley