Архитектура плагинов с интерфейсами;Проверка интерфейса не работает

StackOverflow https://stackoverflow.com/questions/1269608

Вопрос

Я реализую простую архитектуру плагина в приложении.Требования к плагину определяются с помощью интерфейса (IPlugin), который находится в *.dll, на который ссылаются приложение и плагин.В приложении есть менеджер плагинов (также в той же *.dll), который загружает плагины, просматривая все *.dll в папке плагинов, загружает их, а затем проверяет, реализует ли плагин интерфейс.Я выполнил эту проверку двумя разными способами [ранее с помощью простого if (плагин — IPlugin)], но ни один из них не распознал, когда плагин реализует интерфейс.Вот код:

Assembly pluginAssembly = Assembly.LoadFrom(currFile.FullName);
if (pluginAssembly != null)
{
    foreach (Type currType in pluginAssembly.GetTypes())
    {
        if (currType.GetInterfaces().Contains(typeof(IPlugin)))
        {
            // Code here is never executing
            // even when the currType derives from IPlugin
        }
    }                    
}

Раньше я тестировал определенное имя класса («Плагин»), но затем позволял ему циклически перебирать все классы в сборке, но безрезультатно.(Это следует за примером, который я нашел в другом месте.) Чтобы сделать это немного более сложным, есть два интерфейса, каждый из которых реализует исходный интерфейс (iplugina, ipluginb).Плагин фактически реализует один из более специфических интерфейсов (IPluginB).Однако я попробовал это с плагином, просто реализующим более общий интерфейс (IPlugin), и это все равно не работает.

[Редактировать:В ответ на два ответа, которые я впервые получил] Да, я попытался использовать Isassignable от.См. следующее:

Assembly pluginAssembly = Assembly.LoadFrom(currFile.FullName);
if (pluginAssembly != null)
{
    foreach (Type currType in pluginAssembly.GetTypes())
    {
        if (typeof(IPlugin).IsAssignableFrom(currType))
        {
            string test = "test";
        }
    }
}
Это было полезно?

Решение

Попытался ли ты:

typeof(IPlugin).IsAssignableFrom(currType)

Кроме того, типы осуществлять интерфейсы, но они не вывести от них.А BaseType собственность и IsSubclassOf метод показывает вывод, где IsAssignableFrom показывает происхождение или реализацию.

Редактировать: ваши сборки подписаны?Они могут загружаться параллельные версии вашей сборки, и с тех пор Type объекты сравниваются с ReferenceEquals, один и тот же тип в двух параллельных сборках будет полностью независимым.

Редактировать 2: Попробуй это:

public Type[] LoadPluginsInAssembly(Assembly otherAssembly)
{
    List<Type> pluginTypes = new List<Type>();
    foreach (Type type in otherAssembly.GetTypes())
    {
        // This is just a diagnostic. IsAssignableFrom is what you'll use once
        // you find the problem.
        Type otherInterfaceType =
            type.GetInterfaces()
            .Where(interfaceType => interfaceType.Name.Equals(typeof(IPlugin).Name, StringComparison.Ordinal)).FirstOrDefault();

        if (otherInterfaceType != null)
        {
            if (otherInterfaceType == typeof(IPlugin))
            {
                pluginTypes.Add(type);
            }
            else
            {
                Console.WriteLine("Duplicate IPlugin types found:");
                Console.WriteLine("  " + typeof(IPlugin).AssemblyQualifiedName);
                Console.WriteLine("  " + otherInterfaceType.AssemblyQualifiedName);
            }
        }
    }

    if (pluginTypes.Count == 0)
        return Type.EmptyTypes;

    return pluginTypes.ToArray();
}

Другие советы

Метод IsAssignableFrom — это то, что вы ищете:

Type intType = typeof(IInterface);
foreach (Type t in pluginAssembly.GetTypes())
{
    if (intType.IsAssignableFrom(t))
    {
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top