lundi 15 juin 2015

How to pass a strongly typed MarshalByRefObject across an AppDomain boundary?

I have a scenario where I'd like to achieve simple communication between a parent AppDomain and its children. What I'm trying to do looks like it's going to work but I have come upon a snag, the below snippet is an example.

The program results in the message No constructor found for C::.ctor(System.MarshalByRefObject) so it looks like the runtime has rejected the constructor taking a parameter of the type that I'm passing in to the CreateInstanceFromAndUnwrap call. I can understand why instantiating B works and I expected C to behave the same, so why does it not?

Thanks!

using System;
using System.Reflection;

class A : MarshalByRefObject { }

class B : MarshalByRefObject
{
    public B(MarshalByRefObject obj) { }
}

class C : MarshalByRefObject
{
    public C(A obj) { }
}

static class Program
{
    static void Main(string [] args)
    {
        foreach (var type in new [] { typeof(B), typeof(C) })
        {
            try
            {
                var setup = CreateSetup();

                var domain = AppDomain.CreateDomain("foo", AppDomain.CurrentDomain.Evidence, setup);

                CreateWrapped(domain, type);

                AppDomain.Unload(domain);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }

    static AppDomainSetup CreateSetup()
    {
        return new AppDomainSetup
        {
            ApplicationBase = "foo",
            ApplicationName = "bar",
            DisallowBindingRedirects = false,
            ConfigurationFile = "baz",
            LoaderOptimization = LoaderOptimization.MultiDomainHost
        };
    }

    static object CreateWrapped(AppDomain domain, Type type)
    {
        return domain.CreateInstanceFromAndUnwrap(
            assemblyFile: type.Assembly.Location,
            typeName: type.FullName,
            ignoreCase: false,
            bindingAttr: BindingFlags.Default,
            binder: null,
            args: new object[] { new A() },
            culture: null,
            activationAttributes: null
        );
    }
}





Aucun commentaire:

Enregistrer un commentaire