Используя отражение для получения всех классов определенного базового типа в dll

У меня есть dll, который содержит много классов, которые все наследовали от класса CommandBase. Я пытаюсь получить экземпляры всех этих классов (CommandA, CommandB, CommandC, и т.д....) использование отражения в C# так, чтобы я мог назвать определенный метод на каждом. Вот то, что я имею до сих пор:

//get assemblies in directory.
string folder = Path.Combine(HttpContext.Current.Server.MapPath("~/"), "bin");
var files = Directory.GetFiles(folder, "*.dll");
//load each assembly.
foreach (string file in files)
{
  var assembly = Assembly.LoadFile(file);
  if (assembly.FullName == "MyCommandProject")
  {
    foreach (var type in assembly.GetTypes())
    {
      if (!type.IsClass || type.IsNotPublic) continue;
      if(type is CommandBase)
      {
        var command = Activator.CreateInstance(type) as CommandBase;
      }
    }
  }
}

У меня есть 2 проблемы. 1-й выпуск - то, что строка, "если (типом является CommandBase") дает соблюдающее предупреждение:

Данное выражение никогда не имеет обеспеченного типа CommandBase.

2-й выпуск - то, что я не могу выяснить, как получить экземпляр фактического объекта (CommandA, CommandB, и т.д....), просто преобразовывание его к CommandBase не достаточно.

18
задан Greg 28 July 2010 в 14:13
поделиться

4 ответа

Это метод, который я использую для загрузки на основе интерфейса.

private static List<T> GetInstances<T>()
{
        return (from t in Assembly.GetExecutingAssembly().GetTypes()
                where t.GetInterfaces().Contains(typeof (T)) && t.GetConstructor(Type.EmptyTypes) != null
                select (T) Activator.CreateInstance(t)).ToList();
}

А вот та же функция, которая откатывается на основе базового класса.

private static IList<T> GetInstances<T>()
{
        return (from t in Assembly.GetExecutingAssembly().GetTypes()
                       where t.BaseType == (typeof(T)) && t.GetConstructor(Type.EmptyTypes) != null
                       select (T)Activator.CreateInstance(t)).ToList();
}

Конечно, его нужно немного изменить, чтобы он указывал на ссылку, которую вы загружаете.

30
ответ дан 30 November 2019 в 06:42
поделиться

Измените тип с CommandBase на typeof (CommandBase) .IsAssignableFrom (type)

7
ответ дан 30 November 2019 в 06:42
поделиться

Вы должны изменить

if(type is CommandBase) 

на

if(type.IsSubclassOf(typeof(CommandBase)))

, если IsSubclassOf является обратным IsAssignableFrom. То есть, если t1.IsSubclassOf (t2) истинно, то t2.IsAssignableFrom (t1) также истинно.

7
ответ дан 30 November 2019 в 06:42
поделиться

Это потому, что ваша переменная типа является типом Type , а не CommandBase .

Вы хотите

if(type == typeof(CommandBase))

(Спасибо Грегу за исправление)

2
ответ дан 30 November 2019 в 06:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: