How to find all classes in an assembly having a customAttribute?

  • Thread starter Thread starter Sky
  • Start date Start date
S

Sky

Hello:

I understand that I can query an class def to find if it has a specific
custom attribute -- but if i wanted to find all classes in an assembly that
have that attribute, is there a way?

How about methods? Without recursing through every class/every method --
which could get very time consuming?

(PS: To give context to the above question: I am thinking of trying to
find/list all WebMethods in an assembly...since I am trying to make an
IhttpHandler that would correctly direct incoming requests to the right
method...)



And while on the subject -- is there a way to find all classes that
implement a specific interface? Ie, can I find all classdefs in an assembly
that inherit from IMyInterface?

Thanks,
Sky
 
Hi Sky,

Sky said:
Hello:

I understand that I can query an class def to find if it has a specific
custom attribute -- but if i wanted to find all classes in an assembly
that
have that attribute, is there a way?

using System.Reflection;

....

Assembly asm = Assembly.LoadFile("MyAssembly.dll");
if (asm != null)
{
foreach(Type t in asm.GetTypes())
{
object[] attributes = t.GetCustomAttributes();
foreach(attr in attributes)
{
if (attr is MyCustomAttribute)
{
....
}
}
}
}
How about methods? Without recursing through every class/every method --
which could get very time consuming?

for methods:

MethodInfo[] methods = t.GetMethods();

Reflection is considered a relatively heavy operation.
And while on the subject -- is there a way to find all classes that
implement a specific interface? Ie, can I find all classdefs in an
assembly
that inherit from IMyInterface?

Yes, and this (IMHO) the preferred way to implement a plugin architecture.

Remember that if you load assemblies into your current running AppDomain,
you have no way to unload them - so it's wise to create a temporary
AppDomain,
load the assemblies that (possibly) contain plugins into it, check them, and
only
load the ones implementing your plugin interface (and the ones you choose)
into
the running AppDomain later.
 
Hi,


Sky said:
Hello:

I understand that I can query an class def to find if it has a specific
custom attribute -- but if i wanted to find all classes in an assembly that
have that attribute, is there a way?

Assembly.GetTypes() should be the start point. From there you will have to
check if the type is a class , using Type.IsClass
How about methods? Without recursing through every class/every method --
which could get very time consuming?

You will have to check only the part of the class where you can apply the
attribute.


Cheers,
 
Sorry, I did not see this before

You can iterate in all the classes from the assembly and then you can use
some method from the Type class to see if it implement that interface, you
can use GetInterface( string ) .

Cheers,
 
Dear Lars:
Thanks very very much:

a) I had totally forgotten that GetTypes() would negate the need to
recurse -- so the process is quite painless!
b) thanks for the reminder on using a different AppDomain.
c) Yes -- the looking for IMyInterface was for exactly that pupose --
looking for plug-in elements :-)

d) But another issue came up last night that this all might might be useful
for -- searching through an assembly for WebService /WebMethod attributes --
it appears that if I want to make a IHttpHandler for webservices, it's going
to all be done by hand, parsing the incoming xml soap message, getting the
SoapAction, getting the arguments deserialized to objects (?part not figured
out) and then instantiating the asked for class..)


Very best,
Sky




Lars Wilhelmsen said:
Hi Sky,

Sky said:
Hello:

I understand that I can query an class def to find if it has a specific
custom attribute -- but if i wanted to find all classes in an assembly
that
have that attribute, is there a way?

using System.Reflection;

...

Assembly asm = Assembly.LoadFile("MyAssembly.dll");
if (asm != null)
{
foreach(Type t in asm.GetTypes())
{
object[] attributes = t.GetCustomAttributes();
foreach(attr in attributes)
{
if (attr is MyCustomAttribute)
{
....
}
}
}
}
How about methods? Without recursing through every class/every method --
which could get very time consuming?

for methods:

MethodInfo[] methods = t.GetMethods();

Reflection is considered a relatively heavy operation.
And while on the subject -- is there a way to find all classes that
implement a specific interface? Ie, can I find all classdefs in an
assembly
that inherit from IMyInterface?

Yes, and this (IMHO) the preferred way to implement a plugin architecture.

Remember that if you load assemblies into your current running AppDomain,
you have no way to unload them - so it's wise to create a temporary
AppDomain,
load the assemblies that (possibly) contain plugins into it, check them, and
only
load the ones implementing your plugin interface (and the ones you choose)
into
the running AppDomain later.

--
Lars Wilhelmsen
http://www.sral.org/
Software Engineer
Teleplan A/S, Norway
 
Dear Ignacio:

Both you and Lars made the answer perfectly clear -- thanks!
GetType/GetInterface -- just what I needed because:

a) I had totally forgotten that GetTypes() would negate the need to
recurse -- so the process is quite painless!
b) Lars reminded me to use a different AppDomain when reflecting across
external assemblies looking for plug-ins....good point.
c) Another issue came up last night that this all might might be useful
for -- searching through an assembly for WebService /WebMethod attributes --
it appears that if I want to make a IHttpHandler for webservices, it's going
to have to be all be done by hand (since the ASP.NET framework always will
expect that asmx page to help with the routing), parsing the incoming xml
soap message, getting the SoapAction, getting the arguments deserialized to
objects (?part not figured out) and then instantiating the asked for
class..)

Very best,
Sky
 
Back
Top