How enumerate all classes with custom class attribute?
Well, you would have to enumerate through all the classes in all the assemblies that are loaded into the current app domain. To do that, you would call the GetAssemblies
method on the AppDomain
instance for the current app domain.
From there, you would call GetExportedTypes
(if you only want public types) or GetTypes
on each Assembly
to get the types that are contained in the assembly.
Then, you would call the GetCustomAttributes
extension method on each Type
instance, passing the type of the attribute you wish to find.
You can use LINQ to simplify this for you:
var typesWithMyAttribute =
from a in AppDomain.CurrentDomain.GetAssemblies()
from t in a.GetTypes()
let attributes = t.GetCustomAttributes(typeof(HelpAttribute), true)
where attributes != null && attributes.Length > 0
select new { Type = t, Attributes = attributes.Cast<HelpAttribute>() };
The above query will get you each type with your attribute applied to it, along with the instance of the attribute(s) assigned to it.
Note that if you have a large number of assemblies loaded into your application domain, that operation could be expensive. You can use Parallel LINQ to reduce the time of the operation (at the cost of CPU cycles), like so:
var typesWithMyAttribute =
// Note the AsParallel here, this will parallelize everything after.
from a in AppDomain.CurrentDomain.GetAssemblies().AsParallel()
from t in a.GetTypes()
let attributes = t.GetCustomAttributes(typeof(HelpAttribute), true)
where attributes != null && attributes.Length > 0
select new { Type = t, Attributes = attributes.Cast<HelpAttribute>() };
Filtering it on a specific Assembly
is simple:
Assembly assembly = ...;
var typesWithMyAttribute =
from t in assembly.GetTypes()
let attributes = t.GetCustomAttributes(typeof(HelpAttribute), true)
where attributes != null && attributes.Length > 0
select new { Type = t, Attributes = attributes.Cast<HelpAttribute>() };
And if the assembly has a large number of types in it, then you can use Parallel LINQ again:
Assembly assembly = ...;
var typesWithMyAttribute =
// Partition on the type list initially.
from t in assembly.GetTypes().AsParallel()
let attributes = t.GetCustomAttributes(typeof(HelpAttribute), true)
where attributes != null && attributes.Length > 0
select new { Type = t, Attributes = attributes.Cast<HelpAttribute>() };
Yes, absolutely. Using Reflection:
static IEnumerable<Type> GetTypesWithHelpAttribute(Assembly assembly) {
foreach(Type type in assembly.GetTypes()) {
if (type.GetCustomAttributes(typeof(HelpAttribute), true).Length > 0) {
yield return type;
}
}
}