Come trovare un'implementazione di un'interfaccia C# nell'assembly corrente con un nome specifico?
-
09-06-2019 - |
Domanda
Ho un'interfaccia chiamata IStep
che può eseguire alcuni calcoli (vedere "Esecuzione nel Regno dei Sostantivi").In fase di esecuzione, voglio selezionare l'implementazione appropriata in base al nome della classe.
// use like this: IStep step = GetStep(sName);
Soluzione
La tua domanda è molto confusa...
Se vuoi trovare tipi che implementano IStep, procedi come segue:
foreach (Type t in Assembly.GetCallingAssembly().GetTypes())
{
if (!typeof(IStep).IsAssignableFrom(t)) continue;
Console.WriteLine(t.FullName + " implements " + typeof(IStep).FullName);
}
Se conosci già il nome del tipo richiesto, fai così
IStep step = (IStep)Activator.CreateInstance(Type.GetType("MyNamespace.MyType"));
Altri suggerimenti
Se l'implementazione ha un costruttore senza parametri, puoi farlo utilizzando la classe System.Activator.Dovrai specificare il nome dell'assembly oltre al nome della classe:
IStep step = System.Activator.CreateInstance(sAssemblyName, sClassName).Unwrap() as IStep;
http://msdn.microsoft.com/en-us/library/system.activator.createinstance.aspx
Sulla base di ciò che altri hanno sottolineato, questo è quello che ho finito per scrivere:
/// /// 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); } }
Bene, Assembly.CreateInstance sembrerebbe essere la strada da percorrere: l'unico problema è che ha bisogno del nome completo del tipo, ad es.compreso lo spazio dei nomi.