1

From this post, I am able to load a dll into an app domain and get the types in that dll and print them in the temporary domain's function if I want to. But I now want to pass these types back to the primary domain (which has Main). I found this thread which says I need to wrap my object in a MarshalByRef type of class and pass it as an argument, and I tried that but I get an exception. Here is what I have (slightly modified from the example given by @Scoregraphic in the first linked thread)

    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();
        }
    }

I get the exception:

Could not load file or assembly 'abc, Version=1.0.0.5, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.

If I remove the tlw argument from the function and remove this assignment, it works just fine. I'm completely stumped on this.

Community
  • 1
  • 1
AzureMinotaur
  • 646
  • 2
  • 9
  • 22
  • This: `domain.CreateInstanceFromAndUnwrap(pathToDll, typeof(InstanceProxy).FullName) as InstanceProxy` must return `null`, because you're creating instance of `InstanceProxy` from abc.dll, and casting it to `InstanceProxy` from main assembly. Are you sure, that this is your actual code? – Dennis Dec 01 '15 at 07:44
  • No it works fine, just bad naming on my part. `path` is the path to the external dll, but `pathToDll` is the path for the primary (Main's) domain. And I am using `pathToDll` in `CreateInstanceFromAndUnwrap`. I'll edit the names to make them more meaningful. – AzureMinotaur Dec 01 '15 at 17:13
  • I believe the problem is that your newly created AppDomain doesn't know your `TypeListWrapper` object because it can't find the DLL which contains it. You might try adding `ApplicationBase = AppDomain.CurrentDomain.BaseDirectory` to your `domainSetup`. – vesan Dec 01 '15 at 22:21

1 Answers1

1

Any privatebinpath must be a subdirectory of any app domains base path. You aren't setting the child app domain base path so it will probably be using the current app domains base path. I'm going to guess that the path to abc.dll is not within a subdirectory of the parent bin folder

jaywayco
  • 5,846
  • 6
  • 25
  • 40
  • That is correct, the external dll is in a completely different folder hierarchy. If I remove ` PrivateBinPath` from the setup object I still get the same error on the same line. How do I solve this? – AzureMinotaur Dec 01 '15 at 22:17
  • Copy the folder that contains abc.dll into the main apps folder and set the new path to abc.dll as the privatebinpath – jaywayco Dec 01 '15 at 22:18
  • Thank you so much jaywayco. I was stuck on this for almost a day, and you have saved me from a lot more frustration :) – AzureMinotaur Dec 02 '15 at 00:24
  • If I directly copy all the dlls into the bin folder things work, but if I make a new folder under bin and then copy them there, I get FileNotFound when I am trying to do GetTypes() on the assembly. Do you know how I can make this work? Do I need to setup the app domain differently? – AzureMinotaur Dec 02 '15 at 19:23
  • Set the privatebinpath to be the new folder under bin – jaywayco Dec 02 '15 at 20:43