Передача значения из другого домена приложения в основной (основной) домен приложения

Из этого сообщения я могу загрузить dll в домен приложения и получить типы в этой dll и распечатать их в функции временного домена, если я хочу. Но теперь я хочу передать эти типы обратно в основной домен (у которого есть Main). Я нашел этот поток, в котором говорится, что мне нужно обернуть мой объект в тип MarshalByRef класса и передать его в качестве аргумента, и я пробовал это, но получаю исключение. Вот что у меня есть (немного изменено из примера, приведенного @Scoregraphic в первом связанном потоке)

    public class TypeListWrapper : MarshalByRefObject
    {
            public Type[] typeList { get; set; }
    }

    internal class InstanceProxy : MarshalByRefObject
    {
        public void LoadLibrary(string path, TypeListWrapper tlw)
        {
            Assembly asm = Assembly.LoadFrom(path);

            var x = asm.GetExportedTypes();//works fine

            tlw.typeList = x;//getting exception on this line
        }
    }

    public class Program
    {

        public static void Main(string[] args)
        {
            string pathToMainDll = Assembly.GetExecutingAssembly().Location;
            string pathToExternalDll = "/path/to/abc.dll";

            try
            {
                AppDomainSetup domainSetup = new AppDomainSetup
                {
                    PrivateBinPath = pathToMainDll 
                };
                AppDomain domain = AppDomain.CreateDomain("TempDomain", null, domainSetup);
                InstanceProxy proxy = domain.CreateInstanceFromAndUnwrap(pathToMainDll , typeof(InstanceProxy).FullName) as InstanceProxy;
                TypeListWrapper tlw = new TypeListWrapper();
                if (proxy != null)
                {
                    proxy.LoadLibrary(pathToExternalDll , tlw);
                }


                AppDomain.Unload(domain);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
            }

            Console.ReadLine();
        }
    }

У меня исключение:

Не удалось загрузить файл или сборку abc, Version = 1.0.0.5, Culture = нейтральный, PublicKeyToken = null или одну из их зависимостей. Система не может найти указанный файл.

Если я удалю аргумент tlw из функции и удалю это назначение, все будет работать нормально. Я совершенно запутался в этом.


person AzureMinotaur    schedule 01.12.2015    source источник
comment
Это: domain.CreateInstanceFromAndUnwrap(pathToDll, typeof(InstanceProxy).FullName) as InstanceProxy должно возвращать null, потому что вы создаете экземпляр InstanceProxy из abc.dll и преобразуете его в InstanceProxy из основной сборки. Вы уверены, что это ваш настоящий код?   -  person Dennis    schedule 01.12.2015
comment
Нет, все работает нормально, просто плохое именование с моей стороны. path - это путь к внешней dll, но pathToDll - это путь к первичному (главному) домену. И я использую pathToDll в CreateInstanceFromAndUnwrap. Я отредактирую имена, чтобы сделать их более значимыми.   -  person AzureMinotaur    schedule 01.12.2015
comment
Я считаю, что проблема в том, что ваш вновь созданный AppDomain не знает ваш TypeListWrapper объект, потому что не может найти DLL, которая его содержит. Вы можете попробовать добавить ApplicationBase = AppDomain.CurrentDomain.BaseDirectory в свой domainSetup.   -  person vesan    schedule 02.12.2015


Ответы (1)


Любой privatebinpath должен быть подкаталогом любого базового пути доменов приложений. Вы не устанавливаете базовый путь дочернего домена приложения, поэтому он, вероятно, будет использовать базовый путь текущего домена приложения. Я собираюсь предположить, что путь к abc.dll не находится в подкаталоге родительской папки bin

person jaywayco    schedule 01.12.2015
comment
Это правильно, внешняя dll находится в совершенно другой иерархии папок. Если я удалю PrivateBinPath из объекта настройки, я все равно получу ту же ошибку в той же строке. Как мне решить эту проблему? - person AzureMinotaur; 02.12.2015
comment
Скопируйте папку, содержащую abc.dll, в основную папку приложений и установите новый путь к abc.dll в качестве privatebinpath. - person jaywayco; 02.12.2015
comment
Большое спасибо, jaywayco. Я застрял в этом почти на день, и вы избавили меня от еще большего разочарования :) - person AzureMinotaur; 02.12.2015
comment
Если я напрямую копирую все библиотеки DLL в папку bin, все работает, но если я создаю новую папку в bin, а затем копирую их туда, я получаю FileNotFound, когда пытаюсь выполнить GetTypes () в сборке. Вы знаете, как я могу заставить это работать? Нужно ли мне настроить домен приложения по-другому? - person AzureMinotaur; 02.12.2015
comment
Установите privatebinpath в качестве новой папки в bin - person jaywayco; 02.12.2015