Verwenden Sie Folgendes, um alle Typen in der aktuellen Assembly abzurufen, die eine bestimmte Schnittstelle implementieren:
private IEnumerable<Type> GetAllTypesThatImplementInterface<T>()
{
return System.Reflection.Assembly.GetExecutingAssembly()
.GetTypes()
.Where(type => typeof(T).IsAssignableFrom(type) && !type.IsInterface);
}
Code language: C# (cs)
Um Instanzen dieser Typen zu erstellen, durchlaufen Sie sie und verwenden Sie Activator.CreateInstance() wie folgt:
foreach (var type in GetAllTypesThatImplementInterface<T>())
{
var instance = (T)Activator.CreateInstance(type);
//do something with instance
}
Code language: C# (cs)
Beispiel – Automatisches Verbinden einer Befehls-Routing-Tabelle
Angenommen, wir möchten eine Befehls-Routing-Tabelle erstellen. Wir haben Befehle und möchten die Befehlshandler automatisch verdrahten.
Dies ähnelt der Funktionsweise von Web-APIs. Sie geben an, welche Route ein Controller verarbeitet. Wenn eine Anfrage eingeht, ruft das Webframework automatisch den Controller auf, der diese Route verarbeitet.
Erstellen Sie die Command Handler-Schnittstelle
public interface ICommandHandler
{
string HandlesCommand { get; }
void Handle(string command, string data);
}
Code language: C# (cs)
Erstellen Sie die Befehls-Routing-Tabelle
Dies lädt alle Typen, die die ICommandHandler-Schnittstelle implementieren, und erstellt eine Map von 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);
}
}
Code language: C# (cs)
Einen Befehl implementieren Handler
Um diese Funktionsweise zu zeigen, erstellen wir einen einfachen Befehlshandler. Es handhabt den „Repeat“-Befehl, indem es die Daten zweimal auf die Konsole schreibt.
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)
Beispiel für die Verwendung der Routing-Tabelle zur automatischen Verarbeitung eines Befehls
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)
Da RepeatDataCommandHandler dem „repeat“-Befehl zugeordnet ist, ruft dieser Code RepeatDataCommandHandler.Handle() auf, der „I repeat:hello world hello world“ an die Konsole ausgibt.