Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a quicker/better way to get Methods that have attribute applied in C#

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!

like image 995
jwwishart Avatar asked Feb 07 '10 22:02

jwwishart


3 Answers

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".

like image 179
Marc Gravell Avatar answered Oct 19 '22 20:10

Marc Gravell


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.

like image 36
Sam Harwell Avatar answered Oct 19 '22 19:10

Sam Harwell


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>
like image 43
Jeff Cyr Avatar answered Oct 19 '22 18:10

Jeff Cyr