Recomposition Confusion

Mar 22, 2010 at 7:17 PM

Good evening,

I just started playing with MEF and came to the point where I wanted to add recomposition to the sample app. As far as I understand it it would allow me to add new plugins/extensions on the fly, while the 'host' application is running.

So basically what I do is I have a LogManager class which looks like this: http://codepaste.net/a8goes. Now naive as I am I thought the

 

[ImportMany(AllowRecomposition = true)]

public List<ILogger> Loggers { get; private set; }

.. will get updated once I drop new .dlls with the proper ILogger Exports in the extensionsDirectory. However, nothing happens... Loggers remains empty. Now when I do a manual directoryCatalog.Reload() it does detect the new .dlls, but not 'load' or add them to Loggers.

I thought, and I'm obviously wrong, that they would get added automatically... Was I overoptimisitc that this might just 'magically' work by adding the AllowRecomposition = true part to the ImportMany attribute? Or how do I properly add/reload all (new) extensions during runtime?

 

Cheers and thanks,

-J

Developer
Mar 22, 2010 at 10:04 PM

See the second comment I posted on your other post at http://mef.codeplex.com/Thread/View.aspx?ThreadId=206918. The problem here is that you are manually querying the container (essentially ignoring the ImportManyAttribute) if you want MEF to manage this object and it's imports then you need to use MEF to compose it via container.ComposeParts(...) or by having MEF construct the LogManager object.

Once you do that then recomposition will work, however it will still not work the way you are trying because the DirectoryCatalog is static and doesn't look for changes to the directory at runtime. You can hook-up your own FileSystemWatcher to that directory and call DirectoryCatalog.Refresh() when you detect a change but it will not happen for you automatically.

Mar 22, 2010 at 10:38 PM

Awesome! It works now.. thanks for the FileSystemWatcher Tip! One last Question: once the (dynamically) added extensions are loaded they cannot be removed anymore during runtime from the filesystem. Is there anyway to trigger an explicit unload of a loaded extension so it can be deleted again from the filesystem without stopping the host application?

 

-J

Developer
Mar 23, 2010 at 12:00 AM

There isn't any easy way to do it. There are a couple tricks you can try though. One you can setup an AppDomain to use a shadow directory so that it will copy the assemblies to the shadow directory before it loads them, however there are some limitations to this and it can be complicated to setup the AppDomain properly. Another way is to create your own shadow directory by making a copy of the extensions directory and loading the the assemblies from the shadow directory, then setup your FileSystemWatcher on the real extensions directory and when any changes occur update your shadow directory. This will essentially allow for the extensions to deleted from the real extensions directory but remain locked and loaded from the shadow directory. If you go with this approach you will likely need to use some other catalog because the normal directory catalog will not work because you still won't be able to delete the files in your shadow directory (although you may be able to move them to another directory not sure).

If you don't absolutely need this functionality I would stay away from doing it because it just complicates the system.