C#:carga todos los tipos que implementan una interfaz en el ensamblado actual

C#:carga todos los tipos que implementan una interfaz en el ensamblado actual

Para obtener todos los tipos en el ensamblaje actual que implementan una interfaz específica, use lo siguiente:

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

Para crear instancias de estos tipos, revíselas y use Activator.CreateInstance(), así:

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

	//do something with instance
}
Code language: C# (cs)

Ejemplo:conexión automática de una tabla de enrutamiento de comandos

Digamos que queremos construir una tabla de enrutamiento de comandos. Tenemos comandos y queremos conectar automáticamente los controladores de comandos.

Esto es similar a cómo funcionan las API web. Usted especifica qué ruta maneja un controlador. Cuando llega una solicitud, el marco web llama automáticamente al controlador que maneja esa ruta.

Crear la interfaz del controlador de comandos

public interface ICommandHandler
{
	string HandlesCommand { get; }
	void Handle(string command, string data);
}
Code language: C# (cs)

Crear la tabla de enrutamiento de comandos

Esto carga todos los tipos que implementan la interfaz ICommandHandler, creando un mapa de comando => controlador de comandos.

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);
	}
}
Code language: C# (cs)

Implementar un comando manejador

Para mostrar este funcionamiento, crearemos un controlador de comandos simple. Maneja el comando "repetir" escribiendo los datos dos veces en la consola.

public class RepeatDataCommandHandler : ICommandHandler
{
	public string HandlesCommand => "repeat";

	public void Handle(string command, string data)
	{
		Console.WriteLine($"I repeat: {data} {data}");
	}
}
Code language: C# (cs)

Ejemplo de uso de la tabla de enrutamiento para manejar automáticamente un comando

static void Main(string[] args)
{
	var commandRoutingTable = new CommandRoutingTableBuilder().GetCommandRoutingTable();

	string command = "repeat";
	string data = "hello world";

	commandRoutingTable[command].Handle(command, data);
}
Code language: C# (cs)

Debido a que RepeatDataCommandHandler está asignado al comando "repetir", este código llama a RepeatDataCommandHandler.Handle(), que genera "Repito:hola mundo hola mundo" en la consola.