Generally speaking objects that are shared between app domains must derive from MarshalByRefObject. You will have an issue with returning the actual type, if the type is defined in the dynamically loaded DLL. Since the type is not available in your AppDomain of your main thread. You may be able to cast it to a base class that is available in a DLL already loaded in the main application thread.
What i have done in the past was to create an interface for the class I wanted to share between app domains. Obviously the interface would be in some base dll shared by both the main application and the dynamically loaded dll.
in your base dll you can declare your interface:
public interface IMyBaseInterface
{
void DoStuff();
}
Then in the dynamically loaded dll, the class implements the interface and derives from MarshalByRefObject:
public class MyDynamicClass : MarshalByRefObject, IMyBaseInterface
{
public void DoStuff()
{
Console.WriteLine("Hello other app domain!");
}
}
The code to load an instance of the object would look like this:
AppDomainSetup ads = new AppDomainSetup();
AppDomain appDomain = AppDomain.CreateDomain(_appDomainName, null, ads);
IMyBaseInterface myObj = (IMyBaseInterface) appDomain.CreateInstanceAndUnwrap(assemblyName, typeName);
myObj.DoStuff();