Использование отражения для получения всех классов определенного базового типа в 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 недостаточно.
Ответы
Ответ 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))
(Спасибо Грегу за исправление)