If you’re working on a MEF (Managed Extensibility Framework) application, you’re probably familiar with its ups and down. On the one hand, MEF is a powerful plugin system, that’s a pleasure to work with once you know it well.
On the other hand, we all encountered strange failures that originated with MEF. Such failures are a nightmare to debug and identify.
There are several reasons why a MEF failure might happen. A common reason is when an exception is thrown in a MEF ImportingConstructor. For example:
[Export(typeof(ILicenseProvider))]
public class LicenseProvider: ILicenseProvider
{
[ImportingConstructor]
public LicenseProvider(ILicenseChecker checker)
{
//The following checks license on the server, but the WiFi just disconnected
//and an Exception is thrown
bool licenseValid = checker.CheckLicenseValid();
...
}
This sort of exceptions can be missed and occur in production.
The result is not very pleasant:
Preventing the Exception
While working on the OzCode extension, I created a simple Roslyn Analyzer to add try/catch statements to all MEF Importing-Constructors. Let’s see it in action:
The **MefImportExceptionAnalyzer** does the following:- Adds a Diagnostic that finds a MEF ImportingConstructor with content that’s not entirely wrapped in a try/catch statement.
- Provides a Code Fix to handle the problem.
- The Code Fix will:
- Add a try/catch statement around the entire content
- Add ErrorNotificationLogger.LogErrorWithoutShowingErrorNotificationUI(“Error in MEF ctor”, e); inside the catch.
- Add a using statement that for the static class ErrorNotificationLogger
Now, when a similar exception happens in production, it will be reported and as a bonus won’t crash the extension with a nasty error dialog.
This Analyzer is available as NuGet as OzCode.VisualStudioExtensionAnalyzers
Writing the Roslyn Analyzer
The code for this analyzer is available on GitHub .
If you’re interested in how such an analyzer is made, or want to change the behavior of the existing analyzer, then read my tutorial Creating a Roslyn Analyzer that wraps code in a try/catch statement .