Como encontrar uma implementação de uma interface C# no assembly atual com um nome específico?
-
09-06-2019 - |
Pergunta
Eu tenho uma interface chamada IStep
que pode fazer alguns cálculos (Veja "Execução no Reino dos Substantivos").Em tempo de execução, quero selecionar a implementação apropriada pelo nome da classe.
// use like this: IStep step = GetStep(sName);
Solução
Sua pergunta é muito confusa...
Se você quiser encontrar tipos que implementem IStep, faça o seguinte:
foreach (Type t in Assembly.GetCallingAssembly().GetTypes())
{
if (!typeof(IStep).IsAssignableFrom(t)) continue;
Console.WriteLine(t.FullName + " implements " + typeof(IStep).FullName);
}
Se você já sabe o nome do tipo necessário, basta fazer isso
IStep step = (IStep)Activator.CreateInstance(Type.GetType("MyNamespace.MyType"));
Outras dicas
Se a implementação tiver um construtor sem parâmetros, você poderá fazer isso usando a classe System.Activator.Você precisará especificar o nome do assembly além do nome da classe:
IStep step = System.Activator.CreateInstance(sAssemblyName, sClassName).Unwrap() as IStep;
http://msdn.microsoft.com/en-us/library/system.ativator.createinstance.aspx
Com base no que outros apontaram, foi isso que acabei escrevendo:
/// /// 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); } }
Bem, Assembly.CreateInstance parece ser o caminho a seguir - o único problema com isso é que ele precisa do nome totalmente qualificado do tipo, ou seja,incluindo o espaço para nome.