Skip to content

Instantly share code, notes, and snippets.

@VacuumBreather
Created April 13, 2020 06:44
Show Gist options
  • Save VacuumBreather/5be8970f9e5f86e1c912ef0ea14c786e to your computer and use it in GitHub Desktop.
Save VacuumBreather/5be8970f9e5f86e1c912ef0ea14c786e to your computer and use it in GitHub Desktop.
/// <summary>
/// Static helper class to debug failed MEF composition.
/// </summary>
public static class MefDebuggingHelper
{
/// <summary>
/// Writes missing import definitions to the debug console.
/// </summary>
/// <param name="container"></param>
[Conditional("DEBUG")]
public static void PrintMissingImports(CompositionContainer container)
{
var missingImports = GetMissingImports( container );
if( missingImports.Count == 0 )
{
return;
}
Debug.WriteLine( string.Empty );
Debug.WriteLine( "=============== Missing Imports ===============" );
foreach( var missing in missingImports )
{
Debug.WriteLine( missing );
}
Debug.WriteLine( "===============================================" );
Debug.WriteLine( string.Empty );
}
private static List<string> GetMissingImports(CompositionContainer container )
{
var brokenExports = GetBrokenExports(container);
return container.Catalog
.SelectMany( part => part.ImportDefinitions )
.Where( impDef => IsInvalidImport(container, impDef) )
.Select( impDef => impDef.ContractName )
.Distinct()
.Where( contract => !contract.Contains( "ExportFactory" ) )
.Where( contract => !brokenExports.Contains( contract ) )
.OrderBy( contract => contract )
.ToList();
}
private static List<string> GetBrokenExports(CompositionContainer container)
{
return container.Catalog
.Where( part => part.ImportDefinitions.Any( impDef => IsInvalidImport(container, impDef) ) )
.SelectMany( part => part.ExportDefinitions )
.Select( exDef => exDef.ContractName )
.Distinct()
.OrderBy( c => c )
.ToList();
}
private static bool IsInvalidImport(CompositionContainer container, ImportDefinition impDef )
{
try
{
container.GetExports( impDef );
}
catch
{
return true;
}
return false;
}
}
@igitur
Copy link

igitur commented Oct 27, 2020

Oh, man, thanks! I was struggling so much with failed imports. End the end due to a typo. But MEF really doesn't make it easy to trace the issue.

@VacuumBreather
Copy link
Author

Oh, man, thanks! I was struggling so much with failed imports. End the end due to a typo. But MEF really doesn't make it easy to trace the issue.

You are very welcome. I'm glad it helped.

@aubinchedotal-bib
Copy link

aubinchedotal-bib commented Nov 4, 2020

Thank you for that !
How/Where would you call PrintMissingError to display the error behind a failed viewmodel instanciation ?

@VacuumBreather
Copy link
Author

Thank you for that !
How/Where would you call PrintMissingError to display the error behind a failed viewmodel instanciation ?

In the bootstrapper after the MEF container has been built.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment