I’d like to run several services from different .dll’s in a isolated way. Basically, all services are derived from RoleEntryPoint , and I want to load each one in a separated AppDomain and run it there in a different thread.
So far, I can locate the service and get its type:
String pathToDll = @"C:\....\bin\Debug\ChildWorkerRole.dll";
Assembly assembly = Assembly.LoadFrom(pathToDll);
Type serviceType = assembly.GetTypes().SingleOrDefault(t => t.BaseType == typeof(RoleEntryPoint));
And also run it in the current AppDomain and Thread:
RoleEntryPoint myRole2 = (RoleEntryPoint)Activator.CreateInstance(serviceType);
if (myRole2.OnStart())
myRole2.Run();
But when I try to run it in a separate in different AppDomain I get an exception:
AppDomain domain = AppDomain.CreateDomain("MyNewDomain");
RoleEntryPoint myRole = (RoleEntryPoint)domain.CreateInstanceFromAndUnwrap(pathToDll, serviceType.FullName);
if (myRole.OnStart())
myRole.Run();
This exception:
System.Runtime.Serialization.SerializationException was unhandled
Message=Type 'ChildWorkerRole.WorkerRole' in assembly 'ChildWorkerRole, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.
Source=mscorlib
StackTrace:
at System.AppDomain.CreateInstanceFromAndUnwrap(String assemblyName, String typeName)
.......
The funny thing is that ChildWorkerRole is actually marked with the SerializableAttribute … but may be because RoleEntryPoint is not, it cannot be done.
Any idea or workaround?
thanks!
In order to work with a type in a separate AppDomain, it, and all of the types you directly use, need to be either marked as
[Serializable], or you need to derive them from MarshalByRefObject.If this is not possible, the only real option is to make a proxy class that you can use which does follow the above criteria, and allow it to manage your types internally.