How to Get all classes with a custom attribute in C#
By FoxLearn 3/12/2025 3:31:34 AM 115
using System.Reflection; var types = Assembly.GetExecutingAssembly().GetTypes().Where(t => t.IsDefined(typeof(ServiceAttribute)));
This code searches for classes in the current assembly that have the [Service]
attribute.
[Service] public class EmailService : IEmailService { public void SendEmail(string to, string subject, string body) { // Send email logic here } }
This can be useful in scenarios like auto-discovery of service classes during application startup or for implementing dependency injection.
In this article, we'll also cover searching across all loaded assemblies, handling inherited custom attributes, and retrieving the values of custom attributes.
Search Across All Loaded Assemblies
To search through all loaded assemblies, use AppDomain.CurrentDomain.GetAssemblies()
to retrieve all the currently loaded assemblies. Then, loop through each assembly and use GetType()
and IsDefined()
to find classes with the specified custom attribute.
var types = from assembly in AppDomain.CurrentDomain.GetAssemblies() from type in assembly.GetTypes() where type.IsDefined(typeof(ServiceAttribute)) select type;
Alternatively, using method syntax, you could do:
AppDomain.CurrentDomain.GetAssemblies() .SelectMany(a => a.GetTypes().Where(t => t.IsDefined(typeof(ServiceAttribute))));
If you want to search in assemblies that haven’t been loaded yet, you can opt for the MetadataReader
approach.
Handle Inherited Custom Attributes
Custom attributes can be inherited.
[Service] public abstract class ServiceBase { public abstract void ExecuteService(); } public class EmailService : ServiceBase { public override void ExecuteService() { // Implement service execution logic here } }
The [Service]
attribute is defined on the ServiceBase
class, and is inherited by EmailService
. Searching for classes with the [Service]
attribute would return both ServiceBase
and EmailService
by default. However, you might want to filter this to only get the derived classes, not the base class.
Filter Out Abstract Classes
You typically wouldn’t want abstract classes to appear in the search results. You can filter them out by checking the Type.IsAbstract
property:
assembly.GetTypes().Where(t => t.IsDefined(typeof(ServiceAttribute)) && !t.IsAbstract)
This would return only EmailService
, excluding the ServiceBase
abstract class.
Filter Out Classes That Inherited the Custom Attribute
By default, IsDefined(customAttributeType)
will return true
even if the attribute is inherited. If you want to avoid returning classes that inherit the attribute but don’t define it themselves, use the inherit
parameter:
assembly.GetTypes().Where(t => t.IsDefined(typeof(ServiceAttribute), inherit: false))
In this case, if EmailService
only inherited the [Service]
attribute from ServiceBase
, it would be excluded from the results.
Getting Custom Attribute Values
When a custom attribute contains values, you may want to extract those values.
For example, consider this Service
attribute with a value for the service type:
[Service("Email")] public class EmailService : IEmailService { // Email service logic }
To retrieve the custom attribute values, use GetCustomAttribute<T>()
to get the attribute object:
var assembly = Assembly.GetExecutingAssembly(); foreach (var type in assembly.GetTypes()) { var serviceAttribute = type.GetCustomAttribute<ServiceAttribute>(); if (serviceAttribute != null) { Console.WriteLine($"Service={type.Name} Type={serviceAttribute.ServiceType}"); } }
If the custom attribute isn’t defined on the type, GetCustomAttribute
will return null
. Otherwise, it returns the custom attribute object, and you can access its properties. For the above code, this would output:
Service=EmailService Type=Email
This allows you to work with the values specified in the custom attribute, providing more detailed information for your application logic.
- Primitive types in C#
- How to set permissions for a directory in C#
- How to Convert Int to Byte Array in C#
- How to Convert string list to int list in C#
- How to convert timestamp to date in C#
- How to Get all files in a folder in C#
- How to use Channel as an async queue in C#
- Case sensitivity in JSON deserialization