C# – Load all types that implement an interface in the current assembly

To get all types in the current assembly that implement a specified interface, use the following:

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

To create instances of these types, loop through them and use Activator.CreateInstance(), like so:

foreach (var type in GetAllTypesThatImplementInterface<T>()) { var instance = (T)Activator.CreateInstance(type); //do something with instance }

Example – Auto-wire a command routing table

Let’s say we want to build a command routing table. We have commands and want to automatically wire up the command handlers.

This is similar to how web APIs work. You specify which route a controller handles. When a request comes in, the web framework automatically calls the controller that handles that route.

Create the Command Handler interface

public interface ICommandHandler { string HandlesCommand { get; } void Handle(string command, string data); }

Create the command routing table

This loads all types that implement the ICommandHandler interface, creating a map of command => command handler.

public class CommandRoutingTableBuilder { public Dictionary<string, ICommandHandler> GetCommandRoutingTable() { var commandRoutingTable = new Dictionary<string, ICommandHandler>(); foreach (var type in GetAllTypesThatImplementInterface<ICommandHandler>()) { var handler = (ICommandHandler)Activator.CreateInstance(type); commandRoutingTable.Add(handler.HandlesCommand, handler); } return commandRoutingTable; } private IEnumerable<Type> GetAllTypesThatImplementInterface<T>() { return System.Reflection.Assembly.GetExecutingAssembly() .GetTypes() .Where(type => typeof(T).IsAssignableFrom(type) && !type.IsInterface); } }

Implement a command handler

To show this working we’ll create a simple command handler. It handles the “repeat” command by writing the data twice to the console.

public class RepeatDataCommandHandler : ICommandHandler { public string HandlesCommand => "repeat"; public void Handle(string command, string data) { Console.WriteLine($"I repeat: {data} {data}"); } }

Example of using the routing table to automatically handle a command

static void Main(string[] args) { var commandRoutingTable = new CommandRoutingTableBuilder().GetCommandRoutingTable(); string command = "repeat"; string data = "hello world"; commandRoutingTable[command].Handle(command, data); }

Because RepeatDataCommandHandler is mapped to the “repeat” command, this code calls RepeatDataCommandHandler.Handle(), which outputs “I repeat: hello world hello world” to the console.

Leave a Comment