views:

106

answers:

4

I have a marker interface something like this:

[AttributeUsage(AttributeTargets.Method, AllowMultiple=false, Inherited=true)]
public class MyAttribute : Attribute
{
}

And i want to apply it to methods on different classes in different assemblies...

Then I want to Get a MethodInfo for all methods that have this attribute applied. I need to search the whole AppDomain and get a reference to all these methods.

I know we can get all types and then get all methods, but is there a quicker/better way to do this? ... or is this the quickest manner to get the information I need?

(I'm using ASP.NET MVC 1.0, C#, ./NET 3.5)

Thanks heaps!

+11  A: 

Ultimately, no - you have to scan them. LINQ makes it fairly pain-free though.

        var qry = from asm in AppDomain.CurrentDomain.GetAssemblies()
                  from type in asm.GetTypes()
                  from method in type.GetMethods()
                  where Attribute.IsDefined(method, typeof(MyAttribute))
                  select method;

Note this only scans loaded assemblies "as is".

Marc Gravell
Thanks for that Marc! And for the linq query... and the warning... Helps me and other too I'm sure. I'm using ASP.NET MVC ... i did testing re: class loading in ASP.NET because I found that some of my unit tests didn't load external assemblies unless a type was referenced... ASP.NET seems to load everything into the AppDomain thankfully...Thanks again.
jwwishart
A: 

I've searched for this a few weeks ago as well. I think there is no easier way.
You might be able to spiffy it up a bit with LINQ.

Zyphrax
That was what I thought too! Thanks
jwwishart
+1  A: 

One thing you should consider is an additional attribute that you can apply to a class/struct, indicating that zero or more methods of that type are marked. That should give you at least an order of magnitude improvement in performance.

If the attribute is user-defined (not built in to the .NET framework), then when you're enumerating the assemblies to get the types, you should skip framework assemblies such as mscorlib and System.

280Z28
Thanks for the perf hints! I'd Vote Up if I could...
jwwishart
+1  A: 

If you really need the performance gain, do as Marc suggested and then cache the results in a file. The next time the application load, if the cached file exists, it can load the appropriate method without parsing every assemblies.

Here is an example of a possible cache file:

<attributeCache>

  <assembly name='Assembly1' filename='Assembly1.dll' timestamp='02/02/2010'>
    <type name='Assembly1.Type1'>
      <method name='Method1'/>
    </type>
  </assembly>

 <assembly name='Assembly2' filename='Assembly2.dll' timestamp='02/02/2010' />
</attributeCache>
SelflessCoder