2014-09-19 3 views
3

У меня есть класс, который будет загружать все сборки в каталог, а затем получить все типы, чтобы увидеть, реализуют ли они интерфейс. Я не могу заставить сравнение типов работать. В отладчике я вижу, что мой тип загружен (тот, который мне интересен), если всегда не удается выполнить сравнение. Если я использую один и тот же код сравнения локально, нет проблем, я получаю ожидаемый результат. Я просто могу сказать, что sting сравнивается с интерфейсами типа, но я предпочел бы знать, что я делаю неправильно.Поиск объектов, реализующих интерфейс из загруженной сборки -how для сравнения типов?

Тесты:

// Fails 
    [Fact] 
    public void FindISerialPortTest() 
    { 
     var path = Directory.GetCurrentDirectory(); 
     var results = FindImplementers.GetInterfaceImplementor<ISerialPort>(path); 
     results.Length.Should().Be(1); 
     results[0].Should().BeAssignableTo<SerialPortWrapper>(); 
    } 

    //Passes 
    [Fact] 
    public void DoesTypeImplementInterfaceTest() 
    { 
     var myType = typeof(SerialPortWrapper); 
     var myInterface = typeof(ISerialPort); 
     FindImplementers.DoesTypeImplementInterface(myType, myInterface).Should().Be(true); 

    } 

Класс:

public class FindImplementers 
{ 

    public static T[] GetInterfaceImplementor<T>(string directory) 
    { 
     if (String.IsNullOrEmpty(directory)) { return null; } //sanity check 

     DirectoryInfo info = new DirectoryInfo(directory); 
     if (!info.Exists) { return null; } //make sure directory exists 

     var implementors = new List<T>(); 

     foreach (FileInfo file in info.GetFiles("*.dll")) //loop through all dll files in directory 
     { 
      Assembly currentAssembly = null; 
      Type[] types = null; 
      try 
      { 
       //using Reflection, load Assembly into memory from disk 
       currentAssembly = Assembly.LoadFile(file.FullName); 
       types = currentAssembly.GetTypes(); 
      } 
      catch (Exception ex) 
      { 
       //ignore errors 
       continue; 
      } 

      foreach (Type type in types) 
      { 
       if (!DoesTypeImplementInterface(type, typeof(T))) 
       { 
        continue; 
       } 
       //Create instance of class that implements T and cast it to type 
       var plugin = (T)Activator.CreateInstance(type); 
       implementors.Add(plugin); 
      } 
     } 
     return implementors.ToArray(); 
    } 

    public static bool DoesTypeImplementInterface(Type type, Type interfaceType) 
    { 
     return (type != interfaceType && interfaceType.IsAssignableFrom(type)); 
    } 

} 

ответ

6

OK - это дало мне ответ: invalidcastexception-when-using-assembly-loadfile

Вот обновленный класс:

public class PluginLoader 
{ 
    public static T[] GetInterfaceImplementor<T>(string directory) 
    { 
     if (String.IsNullOrEmpty(directory)) { return null; } //sanity check 

     DirectoryInfo info = new DirectoryInfo(directory); 
     if (!info.Exists) { return null; } //make sure directory exists 

     var implementors = new List<T>(); 

     foreach (FileInfo file in info.GetFiles("*.dll")) //loop through all dll files in directory 
     { 
      Assembly currentAssembly = null; 
      try 
      { 
       var name = AssemblyName.GetAssemblyName(file.FullName); 
       currentAssembly = Assembly.Load(name); 
      } 
      catch (Exception ex) 
      { 
       continue; 
      } 

      currentAssembly.GetTypes() 
       .Where(t => t != typeof(T) && typeof(T).IsAssignableFrom(t)) 
       .ToList() 
       .ForEach(x => implementors.Add((T)Activator.CreateInstance(x))); 
     } 
     return implementors.ToArray(); 
    } 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^