Wie finde ich eine Implementierung einer C#-Schnittstelle in der aktuellen Assembly mit einem bestimmten Namen?
-
09-06-2019 - |
Frage
Ich habe eine Schnittstelle namens IStep
das kann einige Berechnungen durchführen (siehe „Hinrichtung im Königreich der Substantive").Zur Laufzeit möchte ich die entsprechende Implementierung anhand des Klassennamens auswählen.
// use like this: IStep step = GetStep(sName);
Lösung
Deine Frage ist sehr verwirrend...
Wenn Sie Typen finden möchten, die IStep implementieren, gehen Sie wie folgt vor:
foreach (Type t in Assembly.GetCallingAssembly().GetTypes())
{
if (!typeof(IStep).IsAssignableFrom(t)) continue;
Console.WriteLine(t.FullName + " implements " + typeof(IStep).FullName);
}
Wenn Sie den Namen des gewünschten Typs bereits kennen, tun Sie dies einfach
IStep step = (IStep)Activator.CreateInstance(Type.GetType("MyNamespace.MyType"));
Andere Tipps
Wenn die Implementierung über einen parameterlosen Konstruktor verfügt, können Sie dies mithilfe der System.Activator-Klasse tun.Sie müssen zusätzlich zum Klassennamen den Assemblynamen angeben:
IStep step = System.Activator.CreateInstance(sAssemblyName, sClassName).Unwrap() as IStep;
http://msdn.microsoft.com/en-us/library/system.activator.createinstance.aspx
Basierend auf dem, was andere darauf hingewiesen haben, habe ich letztendlich Folgendes geschrieben:
/// /// Some magic happens here: Find the correct action to take, by reflecting on types /// subclassed from IStep with that name. /// private IStep GetStep(string sName) { Assembly assembly = Assembly.GetAssembly(typeof (IStep)); try { return (IStep) (from t in assembly.GetTypes() where t.Name == sName && t.GetInterface("IStep") != null select t ).First().GetConstructor(new Type[] {} ).Invoke(new object[] {}); } catch (InvalidOperationException e) { throw new ArgumentException("Action not supported: " + sName, e); } }
Nun, Assembly.CreateInstance scheint der richtige Weg zu sein – das einzige Problem dabei ist, dass es den vollständig qualifizierten Namen des Typs benötigt, d. h.einschließlich des Namensraums.