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

От тази публикация мога да заредя 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=neutral, 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