Tengo una aplicación .NET en la que los ensamblajes en AppDomains separados deben compartir objetos serializados que se pasan por valor. Referencia¿Cómo pasar un tipo desconocido entre dos .NET AppDomains?
Ambos conjuntos de un conjunto compartido que define la clase base para la clase de servidor y también define la clase base para el tipo entiy que será pasado entre dominios:
public abstract class ServerBase : MarshalByRefObject
{
public abstract EntityBase GetEntity();
}
[Serializable]
public abstract class EntityBase
{
}
El conjunto de servidor define la clase de servidor y una Implementación concreta del tipo de entidad:
public class Server : ServerBase
{
public override EntityBase GetEntity()
{
return new EntityItem();
}
}
[Serializable]
public class EntityItem : EntityBase
{
}
el montaje de cliente crea el AppDomain
en el que se encuentra alojado el conjunto de servidor y utiliza una instancia de la clase del servidor para solicitar una instancia concreta del tipo de entidad:
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, este enfoque falla con un SerializationException
porque el ensamblaje cliente no tiene conocimiento directo del tipo concreto que se está devolviendo.
He leído que .NET remoting admite tipos desconocidos cuando se utiliza la serialización binaria, pero no estoy seguro de si esto se aplica a mi configuración o cómo configurarla.
Alternativamente, ¿hay alguna otra manera de pasar un tipo concreto desconocido del servidor al cliente, dado que el cliente solo necesita acceder a él a través de su interfaz de clase base conocida.
Gracias por su consejo,
Tim
EDIT:
a lo solicitado por Hans, aquí está el mensaje de excepción y Seguimiento de la pila.
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()
Gracias Hans. Su sugerencia es muy razonable, pero necesito estar seguro de que no presenta un problema adicional. Lo que describí es parte de un escenario de sandboxing, por lo que no quiero que CLR cargue el ensamblado desconocido en el AppDomain primario (que tiene permisos más amplios) si es probable que comprometa la seguridad. ¿Tienes una opinión sobre esto? Gracias de nuevo. –
Use una interfaz, declarada en su propio ensamblado y referenciada por ambos. –
Bien, cambié la clase EntityBase para que sea una interfaz y reside, como antes, en el ensamblado compartido, pero la excepción todavía se lanza (y presumiblemente por la razón que ya ha indicado, que el objeto pasado es desconocido por el cliente). –