views:

67

answers:

2

Please help me on how to list all classes with a specific Attribute within an assembly in C#?

+6  A: 

Example for code that get all serializable types within an assembly:

public IEnumerable<Type> GetTypesWithAttribute(Assembly assembly)
{
    return assembly.GetTypes()
        .Where(type => type.IsDefined(typeof(SerializableAttribute), false));
}

The second argument IsDefined() receives is whether the attribute should be looked on base types too.

A usage example that find all types decorated with MyDecorationAttribute:

public class MyDecorationAttribute : Attribute{}

[MyDecoration]
public class MyDecoratedClass{}

[TestFixture]
public class DecorationTests
{
    [Test]
    public void FindDecoratedClass()
    {
        var currentAssembly = Assembly.GetExecutingAssembly();
        var typesWithAttribute = GetTypesWithAttribute(currentAssembly);
        Assert.That(typesWithAttribute, 
                              Is.EquivalentTo(new[] {typeof(MyDecoratedClass)}));
    }

    public IEnumerable<Type> GetTypesWithAttribute(Assembly assembly)
    {
        return assembly.GetTypes()
            .Where(type => type.IsDefined(typeof(MyDecorationAttribute), false));
    }
}
Elisha
How have I missed IsDefined for so long. That's much easier than GetCustomAttribute().Any()
Rangoric
A: 

I have finally written my own ClassLoader class which supports .NET 2.0, 3.5 and 4.0.

static class ClassLoader
{
    public static IEnumerable<MethodInfo> GetMethodsWithAttribute(Type attributeType, Type type)
    {
        List<MethodInfo> list = new List<MethodInfo>();

        foreach (MethodInfo m in type.GetMethods())
        {
            if (m.IsDefined(attributeType, false))
            {
                list.Add(m);
            }
        }

        return list;
    }

    public static IEnumerable<Type> GetTypesWithAttribute(Type attributeType, string assemblyName)
    {
        Assembly assembly = Assembly.LoadFrom(assemblyName);
        return GetTypesWithAttribute(attributeType, assembly);
    }

    public static IEnumerable<Type> GetTypesWithAttribute(Type attributeType, Assembly assembly)
    {
        List<Type> list = new List<Type>();
        foreach (Type type in assembly.GetTypes())
        {
            if (type.IsDefined(attributeType, false))
                list.Add(type);
        }

        return list;
    }
}
Mark Attwood