Code isolation with the AppDomain class

  • Thread starter Thread starter Jon Shemitz
  • Start date Start date
J

Jon Shemitz

I am responsible for the plugin-loading part of an app. One of the
things the loader has to do is check licensing, and unload any
unlicensed plugins.

I naively did this as:

AppDomain Sandbox = AppDomain.CreateDomain("Sandbox");
try
{
Assembly Suspect = Sandbox.Load(PluginName);
// do some tests on Suspect.GetExportedTypes()
}
finally
{
AppDomain.Unload(Sandbox);
}

The code seemed to work, but it turns out that
Sandbox.Load(PluginName) is actually loading the PluginName into both
the Sandbox AppDomain and the default AppDomain. When I unload
Sandbox, I'm left with all tested plugins still loaded into the
default AppDomain, whether they are licensed or not.

I do NOT want to execute any assemblies: I just want to load my
suspects; do some tests in the temp AppDomain; and return the test
results to the default AppDomain.

It looks like my only option is to use AppDomain.DoCallBack to execute
my tests, and use SetData to store the results. Is there a better way?
 
The reason why the plugin is getting loaded into both appdomains is because
you are loading the plugin in the context of the default appdomain. You need
to write a class that will remotely load the plugin in the context of the
2nd appdomain and then return the results of the license check back to the
default appdomain.

The statement that is causing the problem is
Assembly Suspect = Sandbox.Load(PluginName);

An assembly object is passed by value, which causes the assembly to get
loaded in both the 2nd appdomain and the one in which the Assembly object is
returned to, in this case the default.

You need to create a class derived from MarshalByRefObject, create an
instance of that in the remote appdomain to which you get back a reference
to a transparent proxy, and then call a method on that object that performs
the test. This link describes this fairly well..

http://www.gotdotnet.com/team/clr/AppdomainFAQ.aspx
 
David said:
The reason why the plugin is getting loaded into both appdomains is because
you are loading the plugin in the context of the default appdomain. You need
to write a class that will remotely load the plugin in the context of the
2nd appdomain and then return the results of the license check back to the
default appdomain.

The statement that is causing the problem is
Assembly Suspect = Sandbox.Load(PluginName);

Yes, I know that, thanks.
You need to create a class derived from MarshalByRefObject, create an
instance of that in the remote appdomain to which you get back a reference
to a transparent proxy, and then call a method on that object that performs
the test. This link describes this fairly well..

Ah, yes. That looks much better than using DoCallBack. Thanks.
 
Back
Top