Создайте объект из динамически загружаемой сборки и приведите его к интерфейсу (.NET 2.0) - PullRequest
1 голос
/ 09 ноября 2011

У меня проблема с динамически загруженными сборками и приведением их к интерфейсу.Где моя ошибка?

Основное приложение (загрузка плагинов):

namespace Console_IFce_Test
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Press any key to find IPlugin library...");
            Console.ReadKey();            

            string[] files = Directory.GetFiles(Directory.GetCurrentDirectory(), "*.dll");
            Console.WriteLine("Loading assembly: {0}", Path.GetFileName(files[0]));

            Assembly asm = Assembly.LoadFrom(files[0]);
            //Trying this, but still have problems
            //Assembly asm = Assembly.Load(File.ReadAllBytes(files[0])); 

            foreach (Type t in asm.GetTypes())
            {
                Console.WriteLine("Searching in type {0}... ", t.FullName);

                foreach (Type iface in t.GetInterfaces())
                {
                    Console.WriteLine("Interface found: {0}", iface.FullName);
                }

                if (t is IPlugin)
                {
                    Console.WriteLine("1 - IPlugin found!");
                    IPlugin plugin = (IPlugin)Activator.CreateInstance(t);
                    return;
                }

                if (typeof(IPlugin).IsAssignableFrom(t))
                {
                    Console.WriteLine("2 - IPlugin found!");
                    IPlugin plugin = (IPlugin)Activator.CreateInstance(t);
                    return;
                }
            }

            Console.WriteLine("All operations done! Press any key to exit...");
            Console.ReadKey();
        }
    }
}

Интерфейс:

namespace Console_IFce_Test
{
    interface IPlugin
    {
        int GetZero();
    }
}

И плагин:

namespace Library
{
    public class Plugin : Console_IFce_Test.IPlugin
    {
        public int GetZero()
        {
            return 0;
        }
    }
}

В каталоге с .exe- только 1 .dll (плагин).Итак, вывод:

Press any key to find IPlugin library... 
Loading assembly: Library.dll 
Searching in type Console_IFce_Test.IPlugin... 
Searching in type Library.Plugin... 
Interface found: Console_IFce_Test.IPlugin 
All operations done! Press any key to exit...

Вы видите, что программа обнаружила интерфейс IPlugin в сборке, но когда я пытаюсь сравнить его с интерфейсом (два условных оператора) - они возвращают false.И если я пытаюсь вручную привести его - он возвращает исключение "Не могу привести".

Я обнаружил похожую проблему: Два типа не равны, что должно быть , и автор ответа напишите:

Один и тот же класс / тип, загруженный разными доменами приложений [.NET] или загрузчиками классов [Java], не будут сравниваться и не могут быть назначены друг другу напрямую.

Но я не могу понять, что мне делать?И как?

Ответы [ 2 ]

2 голосов
/ 09 ноября 2011

Вам нужно каким-то образом создать .NET для загрузки сборок в один и тот же контекст, чтобы можно было выполнять приведение типов между этими сборками.

1- Поместите сборку в путь к приложению или GAC, чтобы ее нашла функция Load (не LoadFrom).

2 - Создайте домен приложения и выполните всю работу там.,Вы можете полностью контролировать, где выполняется поиск сборок для домена приложения.

3- Используйте модель надстройки.

Прочтите эту статью, чтобы узнать больше о ваших параметрах: НаилучшееПрактика по сборке Загрузка

2 голосов
/ 09 ноября 2011

В .Net типы различаются как по контексту, так и по имени ...

И LoadFrom загружает типы в контексте, отличном от любых типов, загружаемых нормально в вашу программу

Таким образом, у вас есть два различных типа IPlugin, один загружается в контексте по умолчанию, а другой в контексте LoadFrom. Они не будут сравниваться одинаково, и вы не можете разыгрывать между ними.

Необходимо убедиться, что типы, на которые ссылаются сборки, загруженные с помощью LoadFrom, не могут быть разрешены в контексте LoadFrom, если вы хотите, чтобы они были такими же, как типы, загруженные в контексте по умолчанию.

...