How to Get all classes that implement interface in C#

By FoxLearn 2/4/2025 6:49:28 AM   192
You can use reflection to retrieve all classes in the current assembly that implement a specific interface.

For example:

private IEnumerable<T> GetAllTypesThatImplementInterface<T>()
{
    return System.Reflection.Assembly.GetExecutingAssembly()
        .GetTypes()
        .Where(type => typeof(T).IsAssignableFrom(type) && !type.IsInterface);
}

To create instances of these types, you can loop through the results and use Activator.CreateInstance():

foreach (var type in GetAllTypesThatImplementInterface<T>())
{
    var instance = (T)Activator.CreateInstance(type);

    // Do something with instance
}

Let’s imagine we want to create a notification system. We have different types of notifications (like email, SMS, and push notifications) and we want to automatically wire up the notification handlers.

Think of this as a subscription model, where different types of subscribers (e.g., email, SMS) automatically handle the notifications sent by the system.

Create the Notification Handler interface

public interface INotificationHandler
{
    string NotificationType { get; }
    void Notify(string message);
}

Create the notification handler registry

This registry will load all types that implement the INotificationHandler interface and add them to a dictionary, mapping notification types to their respective handler objects.

public class NotificationHandlerRegistry
{
    public Dictionary<string, INotificationHandler> GetNotificationHandlers()
    {
        var handlerRegistry = new Dictionary<string, INotificationHandler>();

        foreach (var type in GetAllTypesThatImplementInterface<INotificationHandler>())
        {
            var handler = (INotificationHandler)Activator.CreateInstance(type);

            handlerRegistry.Add(handler.NotificationType, handler);
        }

        return handlerRegistry;
    }

    private IEnumerable<Type> GetAllTypesThatImplementInterface<T>()
    {
        return System.Reflection.Assembly.GetExecutingAssembly()
            .GetTypes()
            .Where(type => typeof(T).IsAssignableFrom(type) && !type.IsInterface);
    }
}

Implement a Notification Handler

Now, let’s implement a simple notification handler.

For example, a handler that sends email notifications.

public class EmailNotificationHandler : INotificationHandler
{
    public string NotificationType => "email";

    public void Notify(string message)
    {
        Console.WriteLine($"Sending email with message: {message}");
    }
}

When a notification needs to be sent, the system can look up the appropriate handler in the registry:

static void Main(string[] args)
{
    var handlerRegistry = new NotificationHandlerRegistry().GetNotificationHandlers();

    string notificationType = "email";
    string message = "Hello, you've got a new message!";

    handlerRegistry[notificationType].Notify(message);
}

In this example, since EmailNotificationHandler is mapped to the "email" notification type, the code calls EmailNotificationHandler.Notify(), which outputs Sending email with message: Hello, you've got a new message! to the console.