MEF AggregateModuleCatalog

   using System;
   using System.Collections.Generic;
   using System.Collections.ObjectModel;
   using System.Linq;
   using Microsoft.Practices.Prism.Modularity;

   /// <summary>
   /// Class AggregateModuleCatalog.
   /// </summary>
   public class AggregateModuleCatalog : IModuleCatalog
   {
      /// <summary>
      /// The catalogs
      /// </summary>
      private List<IModuleCatalog> catalogs = new List<IModuleCatalog>();

      /// <summary>
      /// Initializes a new instance of the <see cref="AggregateModuleCatalog"/> class.
      /// </summary>
      public AggregateModuleCatalog()
      {
         this.catalogs.Add(new ModuleCatalog());
      }

      /// <summary>
      /// Gets the catalogs.
      /// </summary>
      /// <value>The catalogs.</value>
      public ReadOnlyCollection<IModuleCatalog> Catalogs
      {
         get
         {
            return this.catalogs.AsReadOnly();
         }
      }

      /// <summary>
      /// Gets all the <see cref="T:Microsoft.Practices.Prism.Modularity.ModuleInfo" /> 
      /// classes that are in the <see cref="T:Microsoft.Practices.Prism.Modularity.ModuleCatalog" />.
      /// </summary>
      /// <value>The modules.</value>
      public IEnumerable<ModuleInfo> Modules
      {
         get
         {
            return this.Catalogs.SelectMany(x => x.Modules);
         }
      }

      /// <summary>
      /// Adds the catalog.
      /// </summary>
      /// <param name="catalog">The catalog.</param>
      /// <exception cref="ArgumentNullException">Throws ArgumentNullException if catalog is null.</exception>
      public void AddCatalog(IModuleCatalog catalog)
      {
         if (catalog == null)
         {
            throw new ArgumentNullException("catalog");
         }

         this.catalogs.Add(catalog);
      }

      /// <summary>
      /// Return the list of <see cref="T:Microsoft.Practices.Prism.Modularity.ModuleInfo" />s that 
      /// <paramref name="moduleInfo" /> depends on.
      /// </summary>
      /// <param name="moduleInfo">The <see cref="T:Microsoft.Practices.Prism.Modularity.ModuleInfo" />
      /// to get the</param>
      /// <returns>An enumeration of <see cref="T:Microsoft.Practices.Prism.Modularity.ModuleInfo" />
      /// that <paramref name="moduleInfo" /> depends on.</returns>
      public IEnumerable<ModuleInfo> GetDependentModules(ModuleInfo moduleInfo)
      {
         var catalog = this.catalogs.Single(x => x.Modules.Contains(moduleInfo));
         return catalog.GetDependentModules(moduleInfo);
      }

      /// <summary>
      /// Returns the collection of <see cref="T:Microsoft.Practices.Prism.Modularity.ModuleInfo" />s
      ///  that contain both the <see cref="T:Microsoft.Practices.Prism.Modularity.ModuleInfo" />s in
      /// <paramref name="modules" />, but also all the modules they depend on.
      /// </summary>
      /// <param name="modules">The modules to get the dependencies for.</param>
      /// <returns>A collection of <see cref="T:Microsoft.Practices.Prism.Modularity.ModuleInfo" />
      ///  that contains both all <see cref="T:Microsoft.Practices.Prism.Modularity.ModuleInfo" />s in 
      /// <paramref name="modules" /> and also all the 
      /// <see cref="T:Microsoft.Practices.Prism.Modularity.ModuleInfo" /> they depend on.</returns>
      public IEnumerable<ModuleInfo> CompleteListWithDependencies(IEnumerable<ModuleInfo> modules)
      {
         var modulesGroupedByCatalog =
            modules.GroupBy<ModuleInfo, IModuleCatalog>(
               module => this.catalogs.Single(catalog => catalog.Modules.Contains(module)));
         return modulesGroupedByCatalog.SelectMany(x => x.Key.CompleteListWithDependencies(x));
      }

      /// <summary>
      /// Initializes the catalog, which may load and validate the modules.
      /// </summary>
      public void Initialize()
      {
         foreach (var catalog in this.Catalogs)
         {
            catalog.Initialize();
         }
      }

      /// <summary>
      /// Adds a <see cref="T:Microsoft.Practices.Prism.Modularity.ModuleInfo" /> to the
      ///  <see cref="T:Microsoft.Practices.Prism.Modularity.ModuleCatalog" />.
      /// </summary>
      /// <param name="moduleInfo">
      /// The <see cref="T:Microsoft.Practices.Prism.Modularity.ModuleInfo" /> to add.
      /// </param>
      public void AddModule(ModuleInfo moduleInfo)
      {
         this.catalogs[0].AddModule(moduleInfo);
      }
   }