MEF + plugin is not updated

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() { // Determine /bin path string binPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins"); string newPath = ""; // Copy files to /bin foreach (string file in Directory.GetFiles(path, extension, SearchOption.TopDirectoryOnly)) { try { DirectoryInfo dInfo = new DirectoryInfo(binPath); DirectoryInfo[] dirs = dInfo.GetDirectories(); int count = dirs.Count() + 1; newPath = binPath + "/" + count; DirectoryInfo dInfo2 = new DirectoryInfo(newPath); if (!dInfo2.Exists) dInfo2.Create(); File.Copy(file, System.IO.Path.Combine(newPath, System.IO.Path.GetFileName(file)), true); } catch { // Not that big deal... Blog readers will probably kill me for this bit of code :-) } } // Create new directory catalog directoryCatalog = new DirectoryCatalog(newPath, extension); directoryCatalog.Refresh(); } public override IQueryable<ComposablePartDefinition> Parts { get { return directoryCatalog.Parts; } } private void RemoveFromBin(string name) { string binPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ""); File.Delete(Path.Combine(binPath, name)); } 

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. "

+4
source share
3 answers

There is no trigger to rebuild, because your directory implementation does not provide notifications. Add INotifyComposablePartCatalogChanged to fix this.

+3
source

I had a similar problem - after copying the detected plugins to the application directory, DirectoryCatalog will not see them even after calling .refresh () in DirectoryCatalog.

I found that following the code resolved the problem. It is best to assume that the file system still needs a moment after the FileSystemWatcher starts alerting it before the MEF can scan the new assembly (possibly to complete some obscure copy operation) and see the parts inside.

System.Threading.Thread.Sleep (1000), however, solved the problem.

+1
source

I believe that MEF can only load one version of the same assembly (I tried using Silverlight)

0
source

Source: https://habr.com/ru/post/1306743/


All Articles