Найти основной класс, который наследуется от X без использования GetTypes?

У меня есть приложение, которое загружает плагины по запросу (использует AppDomain и MarshalByRefObject), и я пытаюсь найти другой способ проверки плагина.

Прямо сейчас я идентифицирую работающие плагины следующим образом:

_pluginAassembly = AppDomain.CurrentDomain.Load(assemblyName);
foreach (var type in _pluginAassembly.GetTypes().Where(type => type.GetInterface("IPluginChat") != null || type.GetInterface("IPlugin") != null))
{
    _instance = Activator.CreateInstance(type, null, null);
    return ((IPlugin)_instance).Check();
}

Однако, если один из плагинов запутан, GetTypes мгновенно выйдет из строя:

Could not load type 'Invalid_Token.0x01003FFF' from assembly 'SimplePlugin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.

Следовательно, этот метод не позволит мне запускать как обфусцированные, так и необфусцированные плагины.

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

Короче говоря, есть ли способ найти мой основной класс, который наследуется от одного из двух упомянутых интерфейсов (IPlugin или IPluginChat), без необходимости использовать GetTypes, который не может прочитать запутанные типы?


person Guapo    schedule 05.01.2016    source источник
comment
Почему вы не используете пользовательские атрибуты для своих классов плагинов?   -  person Waxoft    schedule 05.01.2016


Ответы (1)


Действительно, вы можете использовать ключевое слово «is», оно вернет true, если указанный экземпляр имеет определенный тип.

Вот очень простой пример:

    interface a
    {

        int doIt();

    }

    interface b
    {

        int doItAgain();

    }

    class c : a, b
    {

        public int doIt() { return 1;  }
        public int doItAgain() { return 2;  }

    }

    var instance = new c();

    var isA = instance is a; //true
    var isB = instance is b; //true
    var isAForm = instance is Form; //false
person Gusman    schedule 05.01.2016
comment
Да, но я не знаю имени основного класса, поэтому у меня был цикл. Короче говоря, мне нужен автоматизированный способ найти класс, наследуемый от данного интерфейса, без использования GetTypes и знания имени класса, в отличие от вашего примера... - person Guapo; 05.01.2016
comment
Тогда нет способа узнать типы в сборке, если вы не используете GetTypes. Окружите GetTypes() с помощью try/catch, и если его исключение ReflectionTypeLoadException использует список типов в аргументах исключения, оно будет просто иметь значение null для неудачных типов. Проверьте этот ответ для получения дополнительной информации: stackoverflow.com/questions/7889228/ - person Gusman; 05.01.2016
comment
яблочко, что ответ в вашем комментарии работает;) - person Guapo; 05.01.2016