Подтвердить что ты не робот

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

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

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

У меня две проблемы. Первая проблема заключается в том, что строка "if (type is CommandBase" ) дает следующее предупреждение:

Данное выражение никогда не относится к предоставленному типу CommandBase.

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

Ответ 3

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

if(type is CommandBase) 

к

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

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

Ответ 4

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

Вы хотите

if(type == typeof(CommandBase))

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