Recomposition

Jan 8, 2010 at 7:17 AM

Hi everyone,
I'm using recomposition in order to load plugin at runtime and when the user loads a new plugin I add it to the AggregateCatalog

catalog.Catalogs.Add(new AssemblyCatalog(filename));

But then MEF clears all of the plugin in the collection

[ImportMany(AllowRecomposition = true)]
public ObservableCollection<IPlugin> Plugins { get; set; }

and I find only the last loaded plugin.

Why?

Thanks
Federico

PS: sorry for my poor english

Developer
Jan 12, 2010 at 7:27 PM

Thats interesting I would expect MEF to clear the collection during recomposition but I would also expect it to add all the existing ones (that haven't been removed) and the new ones back to the collection. The code snippets you show look correct so if this isn't the behavior you are seeing then perhaps showing more of your code could help pin-point the problem.

Jan 12, 2010 at 9:26 PM

Thanks for reply :)
That's the code http://www.copypastecode.com/19836/

If you need I can upload the solution, it's only a test project for a blog post!

Thanks
Federico

Developer
Jan 13, 2010 at 5:06 PM

From scanning the code it doesn't look like the initial list of plugins is ever loaded into the Plugins property at all because the AggregateCatalog doesn't initially have any catalogs added to it. Also, possibly unrelated just wanted to point it out,  in your GetLoadedPlugins() method you are not using the Plugins property you are querying the container directly, which sort of defeats the purpose of the Plugins property.

To me it looks like your code will work fine but it will only contain plugins which have had LoadPlugin called for it. 

Jan 14, 2010 at 6:26 AM

Sorry, I've pasted an old copy of the code...the new version is the same but I've added an AssemblyCatalog to the AggregateCatalog and I don't use GetLoadedPlugins anymore

catalog = new AggregateCatalog(new AssemblyCatalog(Assembly.GetExecutingAssembly()));

However, I don't know how, but I've resolved the problem...I think that there was a lot of test code that did some stupid things.

I've another question :)
Can I unload a plugin from mef or better unload the assembly? I've tried to add a TypeCatalog to the AggregateCatalog, remove it, call Dispose() and then delete the .dll where the type resides but I can't do it :)

Thanks
Federico

Developer
Jan 14, 2010 at 4:26 PM

So you can certainly remove a particular assembly catalog from the aggregate catalog which will remove it from MEF's view but you cannot actually unload the assembly from memory. The CLR itself does not support unloading of single assemblies, it only supports unloading entire application domains. There are ways to isolate plugins into their own application domains so they can be loaded/unloaded independently but they are all painfully hard so unless you have some big reason for this isolation I would try to avoid it.

Jan 16, 2010 at 12:46 PM

I've found this post on coding4fun http://blogs.msdn.com/coding4fun/archive/2009/12/28/9941747.aspx and I would try to create an application like that but where I can remove plugin at runtime.
I've found some solutions but I'm also going to try app domain for fun!

Thanks
Federico