I already asked about this on the MEF Codeplex forum, but I have not received an answer yet, so I decided I would try StackOverflow. Here's the original post if anyone is interested (this is just a copy from it):
MEF Codeplex
"Let me first say that I am completely new to MEF (I just opened it today) and am still very pleased with it. However, I ran into a problem that is very frustrating. An application that will have a plug-in architecture and plugins will only be stored in one DLL file (or encoded in the main application). The DLL file must be recompiled at runtime, and the application should recognize this and reload the plugins (I know this is complicated, but this is a requirement). For this I took the http: / approach /blog.maartenballiauw.be/category/MEF.aspx there (look at WebServerDirectoryCatalog.) The main idea is to βcontrol the plugins folder, copy the new / changed assemblies to the web application folder / bin and instruct MEF to load from there.β This is my code, which is probably not correct way to do this, but this is what I found in some samples over the network:
main()... string myExecName = Assembly.GetExecutingAssembly().Location; string myPath = System.IO.Path.GetDirectoryName(myExecName); catalog = new AggregateCatalog(); pluginCatalog = new MyDirectoryCatalog(myPath + @"/Plugins"); catalog.Catalogs.Add(pluginCatalog); exportContainer = new CompositionContainer(catalog); CompositionBatch compBatch = new CompositionBatch(); compBatch.AddPart(this); compBatch.AddPart(catalog); exportContainer.Compose(compBatch);
and
private FileSystemWatcher fileSystemWatcher; public DirectoryCatalog directoryCatalog; private string path; private string extension; public MyDirectoryCatalog(string path) { Initialize(path, "*.dll", "*.dll"); } private void Initialize(string path, string extension, string modulePattern) { this.path = path; this.extension = extension; fileSystemWatcher = new FileSystemWatcher(path, modulePattern); fileSystemWatcher.Changed += new FileSystemEventHandler(fileSystemWatcher_Changed); fileSystemWatcher.Created += new FileSystemEventHandler(fileSystemWatcher_Created); fileSystemWatcher.Deleted += new FileSystemEventHandler(fileSystemWatcher_Deleted); fileSystemWatcher.Renamed += new RenamedEventHandler(fileSystemWatcher_Renamed); fileSystemWatcher.IncludeSubdirectories = false; fileSystemWatcher.EnableRaisingEvents = true; Refresh(); } void fileSystemWatcher_Renamed(object sender, RenamedEventArgs e) { RemoveFromBin(e.OldName); Refresh(); } void fileSystemWatcher_Deleted(object sender, FileSystemEventArgs e) { RemoveFromBin(e.Name); Refresh(); } void fileSystemWatcher_Created(object sender, FileSystemEventArgs e) { Refresh(); } void fileSystemWatcher_Changed(object sender, FileSystemEventArgs e) { Refresh(); } private void Refresh() {
So, all this really works, and after the main code has finished, my IEnumerable variable is actually filled with all the plugins in the DLL (which, if you follow the code, is in the / 1 plugins, so that I can change the dll in the plugins folder). So, now at this point I can recompile the plug-in DLL modules, put them in the Plugins folder, my FileWatcher will detect that it has changed, and then copy it to folder 2, and the directory should point to a new folder. All of this actually works! The problem is that although it seems like every thing is pointed to the right place, my IEnumerable variable is never updated with new plugins. So close, but for now! Any suggestions? I know that this happens so that no dll is actually unloaded and does not cause a memory leak, but this application is for Windows and will probably run at least once a day, and plugins are unlikely to change that often, but that's all Another requirement from the client is that he does this without reloading the application. Thank you
Thanks for any help you can provide, it drives me crazy, inability to figure it out. "