Game Development Reference
Building a Proxy Wrapper
Here is where things get slightly more complicated. Typically, many of the plugin
systems created with .NET load external plugin assemblies into the main AppDomain
of the application. Although this works and you can use event-driven plugins to
your heart's content, these external assemblies can never be unloaded from the
main AppDomain until the application quits. With a lot of loaded plugins, especially
plugins that are only run for a short period of time, the AppDomain can quickly
become swamped with loaded assemblies that degrade performance and consume
valuable system memory.
The solution to this problem does require additional work, but the external plug-
in assemblies will be unloadable. By creating another AppDomain , you can load
external assemblies into it, execute the needed functionality, and then dump the
extra AppDomain when the plugin is no longer needed. There is a catch though.
There is no restriction that can be enforced to stop types within the extra AppDomain
from leaking into the main AppDomain in certain situations.
One particular situation, which frustrated me and required a code refactoring, was
to avoid the use of delegates and events between the two AppDomains . Doing so will
load the plugin class into the main AppDomain , preventing the extra AppDomain from
You cannot directly instantiate a plugin class using the Activator object directly
from the main AppDomain . You must use a MarshalByRefObject that will serve as a
proxy between the two AppDomains . It is also important that you do not return any
object references or types from the proxy class. Use only types that are available to
the main AppDomain (strings to represent type and interface names, for example).
The extra AppDomain is not found in the proxy class, because the proxy class will be
instantiated within the extra AppDomain . The following code describes the proxy
wrapper; the extra AppDomain code will be covered in the next section.
public class PluginProxy : MarshalByRefObject