Wie finde ich eine Implementierung einer C#-Schnittstelle in der aktuellen Assembly mit einem bestimmten Namen?

StackOverflow https://stackoverflow.com/questions/19656

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);
War es hilfreich?

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top