MEF 2.0 – mini series: part 8 (Composition options and exception handling)

2013/02/16

MEF 2.0 – mini series: part 8 (Composition options and exception handling)

this is the last post in the MEF 2.0 mini series.
you can see other posts of this series in here.

this post will wrap-up the series with a quick survey to to the to some changes made for the underline composition process.

MEF, SELA, Export, Import, CompositionContainer, RegistrationBuilder, Catalog

Exception

one of the most painful experience of MEF 1 was its misleading exception’s description. some time it was really hard to figure out the exception roots.  you can read more about MEF 1 issues in here.

MEF 2 was doing a much better job, but still some composition failure are misleading.
my recommendation is to use the IPartImportsSatisfiedNotification which can give you an interception point where you can figure out what went wrong, before MEF is throwing a composition exception.

the pattern that I’m using is to allow default on any imports and validate it on the OnImportsSatisfied method, see the next snippet:

Code Snippet
  1. public class Foo : IPartImportsSatisfiedNotification
  2. {
  3.     [Import(AllowDefault=true)]
  4.     public IIdentity Identity { get; private set; }
  5.  
  6.     [ImportMany]
  7.     public IReflect[] Reflects { get; private set; }
  8.  
  9.     public void OnImportsSatisfied()
  10.     {
  11.         if (Identity == null)
  12.         {
  13.             Trace.WriteLine("Composition failure (Identity)");
  14.             throw new ArgumentNullException("Identity");
  15.         }
  16.  
  17.         if (Reflects == null || Reflects.Length == 0)
  18.         {
  19.             Trace.WriteLine("Composition failure (Reflects)");
  20.             throw new ArgumentNullException("Reflects");
  21.         }
  22.     }
  23. }

Composition options

MEF 2 is exposing some composition tuning options that wasn’t available on MEF 1.
there was some hidden composition assumptions which you couldn’t modified.
I will focus on the DisableSilentRejection options.
silent rejection was added into MEF composition in order to support robust composition of ill functioning plug-ins. the requirement for this feature came from the Visual Studio team which is using MEF for their plug-in model.
anyway you might want to alter this behavior. MEF 2 doe’s let you the option to disable it.
the original behavior will exclude the ill functioning plug-in from the composition (for import many) without throwing an exception.
this led to scenarios when you had a real hard time to figure out why some of the plug-in wasn’t loading and still everything seem to be working.

the following snippet is demonstrating this scenario:

Code Snippet
  1. class Program
  2. {
  3.     static void Main(string[] args)
  4.     {
  5.         var p = new Program();
  6.  
  7.         var cat = new AssemblyCatalog(Assembly.GetExecutingAssembly());
  8.         var container = new CompositionContainer(cat, CompositionOptions.DisableSilentRejection);
  9.  
  10.         try
  11.         {
  12.             container.ComposeParts(p);
  13.             Console.WriteLine("{0} Plug-ins loaded", p.Plugins.Length);
  14.         }
  15.         catch (CompositionException)
  16.         {
  17.             Console.WriteLine("Composition error");
  18.         }
  19.     }
  20.  
  21.     [ImportMany]
  22.     public Iplugin[] Plugins { get; set; }
  23. }
  24.  
  25. [InheritedExport]
  26. public interface Iplugin { }
  27.  
  28. public class BadPlugin : Iplugin
  29. {
  30.     [Import(typeof(IIdentity))]
  31.     public IIdentity MissingDependency { get; set; }
  32. }
  33.  
  34. public class FinePlugin : Iplugin { }

line 8: disabling the silent rejection behavior.
line 28 – 32: a class that is having a missing dependencies, therefore cannot be construct. on silent rejection mode (which is the default) it will be simply removed from the composition and the Plugins property at line 22 will get a single plug-in rather then 2.

Summary

MEF 2 is having improvements both in the engine and the API level.
you do have more control over the composition and better descriptive exception.

Shout it

Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>