Working with dynamically loaded assemblies in a separate AppDomain is a powerful tool for protecting your execution context and creating a pluggable arcitecture. Brad Smith has written a great post on how to set it up using a generic architecture.
There is one issue with the way he set it up for a project I have been involved in which resulted in us getting the dreaded remoting exception “Object: has been disconnected or does not exist at the server.”
Object '/**GUID**/**CRAZYNAME**.rem' has been disconnected or does not exist at the server. InnerMessage: StackTrace: Server stack trace: at System.Runtime.Remoting.Channels.ChannelServices.CheckDisconnectedOrCreateWellKnownObject(IMessage msg) at System.Runtime.Remoting.Channels.ChannelServices.SyncDispatchMessage(IMessage msg) Exception rethrown at : at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
In our scenario the ISponsor implementation needed to inherit from MarshalByRefObject in order for the renewals to work. Turns out it wasn’t the ISponsor MarshalByRefObject inheritance that fixed it. We had a couple of complex parameters (custom classes) passed into the new AppDomain and these instances were being disconnected from the New AppDomain since they were created in the Initial AppDomain so they also needed to have an ISponsor.
For good measure we even tried adding a separate sponsor for the sponsor! But this wasn’t necessary since the sponsor is tracked elsewhere (as far as I understand) and gets called for renewal when the lease expires. The renewal call should renew the sponsors own lease so I guess it should never timeout.
There is a great article on MSDN about the whole sponsorship, leasing & AppDomains topic.