MEF CompositionContainer.ComposeParts - loading all possible solutions and ignoring errors

The biggest problem that I still encounter with MEF is that when I compose the details in my plugin loader shell, the download completes completely when it finds the problem of allowing import from one of the assemblies. Ideally, I would like ComposeParts to show some kind of โ€œignore and continueโ€ behavior, because an ideal user interface entails loading as many plugins as possible and simply logs an event when a particular plugin fails to load. I could not find information about this in the documentation anywhere.

If you have any other suggestions on how to solve this, Iโ€™m listening!

+3
source share
2 answers

The Wim example has basic ideas, but instead of directly clicking on the container, I suggest you make Lazy ImportMany, for example:

[Export]
public class MyApplication
{
   [ImportMany(typeof(IPlugin))]
   public IEnumerable<Lazy<IPlugin>> Plugins { get; set; }
}

Then you can initialize the plugins one at a time and catch any errors from them, for example:

void InitializePlugins()
{
   foreach (Lazy<IPlugin> plugin in Plugins)
   {
       try
       {
          plugin.Value.Initialize();
       }
       catch (CompositionException e)
       {
          // Handle the error accordingly
       }
   }   
}

The actual plugin will not be created until you click. Highlight the first time, and that's when errors will occur if the plugin has errors in the constructor or import settings. Also note that I will catch a CompositionException, which will be what will exit the .Value call if the plugin does something wrong.

+8
source

AllowDefault. true , null, .

public class MyComponent
{
    [Import(AllowDefault=true)]
    public IMyDependency MyDependency { get; set; }
}

, , - , [ImportMany] , :

[Export]
public class MyApplication
{
   [ImportMany(typeof(IPlugin))]
   public IEnumerable<IPlugin> Plugins { get; set; }
}

, , . , , . , , :

IEnumerable<IPlugin> GetPluginsFromContainer(CompositionContainer container)
{
   foreach (Lazy<IPlugin> pluginExport in container.GetExports<IPlugin>())
   {
       try
       {
          yield return pluginExport.Value;
       }
       catch (Exception e)
       {
          // report failure to instantiate plugin somewhere
       }
   }   
}
+2

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


All Articles