Как найти реализацию интерфейса C# в текущей сборке с определенным именем?


6

У меня есть интерфейс под названием IStep, который может выполнять некоторые вычисления (см. «Execution in the Kingdom of Nouns»). Во время выполнения я хочу выбрать соответствующую реализацию по имени класса.

 
// use like this: 
IStep step = GetStep(sName); 
8

Ваш вопрос очень запутанный ...

Если вы хотите, чтобы найти типы, которые реализуют Истэп, то сделать это:

foreach (Type t in Assembly.GetCallingAssembly().GetTypes()) 
{ 
    if (!typeof(IStep).IsAssignableFrom(t)) continue; 
    Console.WriteLine(t.FullName + " implements " + typeof(IStep).FullName); 
} 

Если вы уже знаете название нужного типа, просто сделать это

IStep step = (IStep)Activator.CreateInstance(Type.GetType("MyNamespace.MyType")); 

2

Если реализация имеет конструктор без параметров, вы можете сделать это, используя класс System.Activator. Вам нужно будет указать имя сборки в дополнении к имени класса:

IStep step = System.Activator.CreateInstance(sAssemblyName, sClassName).Unwrap() as IStep; 

http://msdn.microsoft.com/en-us/library/system.activator.createinstance.aspx


1

Основываясь на том, что другие указали, это то, что я в конечном итоге написание:

 
/// 
/// 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); 
    } 
} 

0

Ну Assembly.CreateInstance, казалось бы, путь - единственная проблема состоит в том, что она нуждается полное имя типа, т.е. включая пространство имен.