I have a .NET application in which assemblies in separate AppDomains must share serialized objects that are passed by value.
Both assemblies reference a shared assembly that defines the base class for the server class and also defines the base class for the entiy type that will be passed between domains:
public abstract class ServerBase : MarshalByRefObject
{
public abstract EntityBase GetEntity();
}
[Serializable]
public abstract class EntityBase
{
}
The server assembly defines the server class and a concrete implemetation of the entity type:
public class Server : ServerBase
{
public override EntityBase GetEntity()
{
return new EntityItem();
}
}
[Serializable]
public class EntityItem : EntityBase
{
}
The client assembly creates the AppDomain
in which the server assembly will be hosted and uses an instance of the server class to request a concrete instance of the entity type:
class Program
{
static void Main()
{
var domain = AppDomain.CreateDomain("Server");
var server = (ServerBase)Activator.CreateInstanceFrom(
domain,
@"..\..\..\Server\bin\Debug\Server.dll",
"Server.Server").Unwrap();
var entity = server.GetEntity();
}
}
Unfortnately, this approach fails with a SerializationException
because the client assembly has no direct knowledge of the concrete type that is being returned.
I have read that .NET remoting supports unknown types when using binary serialization, but I am not sure whether this applies to my setup or how to configure it.
Alternatively, is there any other way of passing an unknown concrete type from the server to the client, given that the client only needs to access it via its known base class interface.
Thanks for your advice,
Tim
EDIT:
As requested by Hans, here is the exception message and stack trace.
SerializationException
Type is not resolved for member 'Server.EntityItem,Server, Version=1.0.0.0,Culture=neutral, PublicKeyToken=null'.
at Interop.ServerBase.GetEntity()
at Client.Program.Main() in C:\Users\Tim\Visual Studio .Net\Solutions\MEF Testbed\Client\Program.cs:line 12
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
I asked a related question a while back: