views:

39

answers:

2

Is there a way to release an object that was accessed using late-binding (i.e. created by the Activator.CreateInstance() method)?

I have an application that transforms files from one format to another. The assemblies that perform these translations live in a folder in my application directory.

When the application first starts up, I can delete these assemblies from the translation folder without any errors. However, once I process a document through the application (and have bound to one of the translation assemblies using late-binding), I can no longer delete the translation assemblies. At this point, I'm receiving an error message stating that the file is "in use by another application".

Is there a way to "release" the late-bound object in my application once I'm finished using it?

A: 

Once an assembly is loaded into the executing AppDomain, it cannot be unloaded (regardless of whether it is creating via reflection with Activator.CreateInstance).

The recommended approach here is to implement a secondary AppDomain with a lifetime that can unload when it wants to dispose the assemblies.

There are tons of examples, but here is one: http://www.dotnet247.com/247reference/msgs/28/142174.aspx.

Since managing the lifetime of secondary AppDomains can be a pain, as an alternative, if you are using ASP .NET and are looking to load many dynamic assemblies, you can check when your current AppDomain becomes saturated with dynamically loaded assemblies by binding to the AppDomain.CurrentDomain.AssemblyLoaded event and keeping count, then requesting the hosting environment recycle the current AppDomain when it hits a critical number (say 500) like:

HostingEnvironment.InitiateShutdown();
JeffN825
A: 

Once an assembly is loaded into an application domain it'll remain until the app domain shuts down.

To get around this load the assembly into it's own application domain, for example:

AppDomain app = AppDomain.CreateDomain("PlugInDomain");
ObjectHandle objectHandle = app.CreateInstanceFrom(assemblyPath, 
             "MyNamespace.MyComponent");
MyComponent component = (MyComponent) objectHandle.Unwrap();

// do stuff

// Now kill app domain, assembly can be overwritten after this.
AppDomain.Unload(app);
Kev
Perfect!! Thanks Kev!!
pmartin