Comment trouver une implémentation d'une interface C# dans l'assembly actuel avec un nom spécifique ?
-
09-06-2019 - |
Question
J'ai une interface appelée IStep
qui peut faire quelques calculs (Voir "Exécution au Royaume des Noms").Au moment de l'exécution, je souhaite sélectionner l'implémentation appropriée par nom de classe.
// use like this: IStep step = GetStep(sName);
La solution
Votre question est très confuse...
Si vous souhaitez rechercher des types qui implémentent IStep, procédez comme suit :
foreach (Type t in Assembly.GetCallingAssembly().GetTypes())
{
if (!typeof(IStep).IsAssignableFrom(t)) continue;
Console.WriteLine(t.FullName + " implements " + typeof(IStep).FullName);
}
Si vous connaissez déjà le nom du type requis, faites simplement ceci
IStep step = (IStep)Activator.CreateInstance(Type.GetType("MyNamespace.MyType"));
Autres conseils
Si l'implémentation dispose d'un constructeur sans paramètre, vous pouvez le faire à l'aide de la classe System.Activator.Vous devrez spécifier le nom de l'assembly en plus du nom de la classe :
IStep step = System.Activator.CreateInstance(sAssemblyName, sClassName).Unwrap() as IStep;
http://msdn.microsoft.com/en-us/library/system.activator.createinstance.aspx
Sur la base de ce que d'autres ont souligné, voici ce que j'ai fini par écrire :
/// /// 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); } }
Eh bien, Assembly.CreateInstance semble être la voie à suivre - le seul problème est qu'il a besoin du nom complet du type, c'est-à-direy compris l'espace de noms.