MefUtils.cs 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel.Composition.Hosting;
  4. using System.ComponentModel.Composition.Primitives;
  5. using System.Linq;
  6. using System.Reflection;
  7. namespace MediaBrowser.Common.Mef
  8. {
  9. /// <summary>
  10. /// Class MefUtils
  11. /// </summary>
  12. public static class MefUtils
  13. {
  14. /// <summary>
  15. /// Plugins that live on both the server and UI are going to have references to assemblies from both sides.
  16. /// But looks for Parts on one side, it will throw an exception when it seems Types from the other side that it doesn't have a reference to.
  17. /// For example, a plugin provides a Resolver. When MEF runs in the UI, it will throw an exception when it sees the resolver because there won't be a reference to the base class.
  18. /// This method will catch those exceptions while retining the list of Types that MEF is able to resolve.
  19. /// </summary>
  20. /// <param name="catalogs">The catalogs.</param>
  21. /// <returns>CompositionContainer.</returns>
  22. /// <exception cref="System.ArgumentNullException">catalogs</exception>
  23. public static CompositionContainer GetSafeCompositionContainer(IEnumerable<ComposablePartCatalog> catalogs)
  24. {
  25. if (catalogs == null)
  26. {
  27. throw new ArgumentNullException("catalogs");
  28. }
  29. var newList = new List<ComposablePartCatalog>();
  30. // Go through each Catalog
  31. foreach (var catalog in catalogs)
  32. {
  33. try
  34. {
  35. // Try to have MEF find Parts
  36. catalog.Parts.ToArray();
  37. // If it succeeds we can use the entire catalog
  38. newList.Add(catalog);
  39. }
  40. catch (ReflectionTypeLoadException ex)
  41. {
  42. // If it fails we can still get a list of the Types it was able to resolve and create TypeCatalogs
  43. var typeCatalogs = ex.Types.Where(t => t != null).Select(t => new TypeCatalog(t));
  44. newList.AddRange(typeCatalogs);
  45. }
  46. }
  47. return new CompositionContainer(new AggregateCatalog(newList));
  48. }
  49. /// <summary>
  50. /// Gets a list of types within an assembly
  51. /// This will handle situations that would normally throw an exception - such as a type within the assembly that depends on some other non-existant reference
  52. /// </summary>
  53. /// <param name="assembly">The assembly.</param>
  54. /// <returns>IEnumerable{Type}.</returns>
  55. /// <exception cref="System.ArgumentNullException">assembly</exception>
  56. public static IEnumerable<Type> GetTypes(Assembly assembly)
  57. {
  58. if (assembly == null)
  59. {
  60. throw new ArgumentNullException("assembly");
  61. }
  62. try
  63. {
  64. return assembly.GetTypes();
  65. }
  66. catch (ReflectionTypeLoadException ex)
  67. {
  68. // If it fails we can still get a list of the Types it was able to resolve
  69. return ex.Types.Where(t => t != null);
  70. }
  71. }
  72. }
  73. }