Simply create remote host object in the main AppDomain
and pass it to the newly initialized child domain. Whenever the child want to send data to the host, use this remote host object.
// This class provides callbacks to the host app domain.
// As it is derived from MarshalByRefObject, it will be a remote object
// when passed to the children.
// if children are not allowed to reference the host, create an IHost interface
public class DomainHost : MarshalByRefObject
{
// send a message to the host
public void SendMessage(IChild sender, string message)
{
Console.WriteLine($"Message from child {sender.Name}: {message}");
}
// sends any object to the host. The object must be serializable
public void SendObject(IChild sender, object package)
{
Console.WriteLine($"Package from child {sender.Name}: {package}");
}
// there is no timeout for host
public override object InitializeLifetimeService()
{
return null;
}
}
I suspect that the children object you create already implement an interface so you can reference them from the main domain without loading their actual type. On initialization you can pass them the host object so after the initialization you can do callbacks from the children.
public interface IChild
{
void Initialize(DomainHost host);
void DoSomeChildishJob();
string Name { get; }
}
ChildExample.dll:
internal class MyChild : MarshalByRefObject, IChild
{
private DomainHost host;
public void Initialize(DomainHost host)
{
// store the remote host here so you will able to use it to send feedbacks
this.host = host;
host.SendMessage(this, "I am being initialized.")
}
public string Name { get { return "Dummy child"; } }
public void DoSomeChildishJob()
{
host.SendMessage(this, "Job started.")
host.SendObject(this, 42);
host.SendMessage(this, "Job finished.")
}
}
Usage:
var domain = AppDomain.CreateDomain("ChildDomain");
// use the proper assembly and type name.
// child is a remote object here, ChildExample.dll is not loaded into the main domain
IChild child = domain.CreateInstanceAndUnwrap("ChildExample", "ChildNamespace.MyChild") as IChild;
// pass the host to the child
child.Initialize(new DomainHost());
// now child can send feedbacks
child.DoSomeChildishJob();