Code isolation with the AppDomain class

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?
 
D

David Levine

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
 
J

Jon Shemitz

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top