Question

I'm creating an AppDomain with a different ApplicationBase, and then loading an assembly from outside of this ApplicationBase into the domain.

Instantiating a MarshalByRef type from it with CreateInstanceFromAndUnwrap works just fine, and I can even use that type—until I try to pass an instance of a custom type as an argument to it. Even if this and the argument are from the exact same assembly, I get this exception:

System.ArgumentException: Object type cannot be converted to target type.

When I don't set ApplicationBase the problem goes away. But I need to set this. Why is this happening? How can I get around this issue? Here is a full test case:

using System;
using System.Linq;

namespace adtest
{
    class Program
    {
        static void Main(string[] args)
        {
            AppDomainSetup ads = new AppDomainSetup
            {
                ApplicationBase = "C:\\", // just to have it be different.
                ApplicationName = "test server"
            };

            AppDomain ad = AppDomain.CreateDomain(
                ads.ApplicationName, null, ads);

            ReverseFactory rf = (ReverseFactory)ad.CreateInstanceFromAndUnwrap(
                typeof(ReverseFactory).Assembly.Location,
                typeof(ReverseFactory).FullName);

            string res = rf.Reverse(
                new StringHolder("Hello from Bizarro Domain"));

            Console.WriteLine(res);
        }
    }

    public class ReverseFactory : MarshalByRefObject
    {
        public string Reverse(StringHolder s)
        {
            return new string(s.Value.Reverse().ToArray());
        }
    }

    public class StringHolder : MarshalByRefObject
    {
        public string Value { get; set; }
        public StringHolder(string s) { Value = s; }
    }
}

When I make StringHolder serializable instead of MarshalByRef it works. However, my actual much larger code that this test represents can not use a serializable object.

Was it helpful?

Solution

From your sample code I understand that you want to pass a proxy object from your main AppDomain (StringHolder), to the proxy object in the child AppDomain (ReverseFactory). At the same time you want the two AppDomains to have different base dirs.

One way to achieve this is by installing the assembly to the GAC. There probably is another way to handle this but, at the moment, it escapes me.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top