System.InvalidCastException: 'Unable to cast transparent proxy to type 'newdomaintest0912.Animal'.' when pass an object from default appdomain to child appdomain

Jiang, Zhiyou (蒋志友) 0 Reputation points
2023-09-13T10:07:46.4133333+00:00

I create a child domain, if I set ApplicationBase as the other directory which is not the same as the main application , I create an object which is inherit from MarshalByRefObject in default domain then transmit it to child domain, child domain cannot cast it as actual type, it throw System.InvalidCastException: 'Unable to cast transparent proxy to type 'newdomaintest0912.Animal'.' exception, but if I set ApplicationBase as AppDomain.CurrentDomain.BaseDirectory, the problem will go away.

I need to set it as a different directory, is there a way to implement it.

below is the code.

class Program
    {
        static void Main(string[] args)
        {

            var adl = new ScriptDynamicLoader();

            var _ = new Animal();
            _.Name = "Cat";
            _.Ege = 2;
            var hand = new System.Runtime.Remoting.ObjectHandle(_);
            adl.remoteLoader.printObject(new System.Runtime.Remoting.ObjectHandle(_));

        }
    }
namespace newdomaintest0912
{
    public class ScriptDynamicLoader
    {
        private AppDomain appDomain;

        public readonly RemoteLoader remoteLoader;
        public ScriptDynamicLoader()
        {
            AppDomainSetup setup = new AppDomainSetup();
            setup.ApplicationBase = @"C:\Users\zjiae07737\source\repos\Scripting20Spike\Script2\bin\Debug";
            //setup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;

            appDomain = AppDomain.CreateDomain("ScriptDomain", null, setup);
            remoteLoader = appDomain.CreateInstanceFromAndUnwrap(typeof(RemoteLoader).Assembly.Location, typeof(RemoteLoader).FullName) as RemoteLoader;

        }
    }

    public class RemoteLoader : MarshalByRefObject
    {
        public ObjectHandle getObject()
        {
            var _ = new Animal();
            _.Name = "Dog";
            _.Ege = 10;
            Console.WriteLine(AppDomain.CurrentDomain.Id);
            return new ObjectHandle(_);
        }

        public void printObject (ObjectHandle objectHandle)
        {
            var wrap = objectHandle.Unwrap();
            var ami = (Animal)wrap;

            ami.print();
        }
    }


    public class Animal : MarshalByRefObject
    {
        public string Name;
        public int Ege;


        public void print()
        {
            Console.WriteLine($"The name is {Name}, the age is {Ege}. The domain id is {AppDomain.CurrentDomain.Id}.");
        }

    }
}
Developer technologies | C#
Developer technologies | C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
{count} votes

1 answer

Sort by: Most helpful
  1. Anonymous
    2023-09-13T11:20:56.61+00:00

    Hi @Jiang, Zhiyou , Welcome to Microsoft Q&A,

    In code, when you set a different directory as a subdirectory, the .NET runtime treats the child class as a different type than the class in the parent class, even though they have the same name and namespace.

    Do you mean this?

    using System;
    
    namespace _9_13_x
    {
        internal class Program
        {
            static void Main(string[] args)
            {
                var adl = new ScriptDynamicLoader();
    
                // Use IAnimal interface instead of Animal.
                var animal = adl.remoteLoader.getObject();
                adl.remoteLoader.printObject(animal);
                Console.ReadLine();
            }
        }
    
        public class ScriptDynamicLoader
        {
            private AppDomain appDomain;
    
            public readonly RemoteLoader remoteLoader;
            public ScriptDynamicLoader()
            {
                AppDomainSetup setup = new AppDomainSetup();
                setup.ApplicationBase = @"C:\Users\Administrator\Desktop\";
                appDomain = AppDomain.CreateDomain("ScriptDomain", null, setup);
                remoteLoader = appDomain.CreateInstanceFromAndUnwrap(typeof(RemoteLoader).Assembly.Location, typeof(RemoteLoader).FullName) as RemoteLoader;
            }
        }
    
        public class RemoteLoader : MarshalByRefObject
        {
            public IAnimal getObject()
            {
                var animal = new Animal();
                animal.Name = "Dog";
                animal.Ege = 10;
                Console.WriteLine(AppDomain.CurrentDomain.Id);
                return animal;
            }
    
            public void printObject(IAnimal animal)
            {
                animal.print();
            }
        }
    
        // Define a shared interface without MarshalByRefObject.
        public interface IAnimal
        {
            void print();
        }
    
        // Modify the Animal class to inherit from MarshalByRefObject and implement the shared interface.
        public class Animal : MarshalByRefObject, IAnimal
        {
            public string Name;
            public int Ege;
    
            public void print()
            {
                Console.WriteLine($"The name is {Name}, the age is {Ege}. The domain id is {AppDomain.CurrentDomain.Id}.");
            }
        }
    }
    

    enter image description here

    Best Regards,

    Jiale


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment". 

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.