コード例 #1
0
        /// <summary>
        /// <see cref="ILogger"/>生成処理
        ///
        /// https://mef.codeplex.com/wikipage?title=ProgrammingModelExtensions&referringTitle=Documentation
        /// </summary>
        /// <param name="contract"></param>
        /// <param name="descriptorAccessor"></param>
        /// <returns></returns>
        public override IEnumerable <ExportDescriptorPromise> GetExportDescriptors(CompositionContract contract, DependencyAccessor descriptorAccessor)
        {
            if (contract.ContractType == typeof(ILogger))
            {
                string value = string.Empty;
                CompositionContract unwrap;

                contract.TryUnwrapMetadataConstraint("LogType", out value, out unwrap);

                string header = string.Format("[{0}] LogExportDescriptorProvider - ", value);

                return(new ExportDescriptorPromise[]
                {
                    new ExportDescriptorPromise(
                        contract,
                        "ConsoleMef2 ILogger",
                        true,
                        NoDependencies,
                        _ => ExportDescriptor.Create((c, o) => new Logger()
                    {
                        Header = header
                    }, NoMetadata)
                        )
                });
            }
            else
            {
                return(NoExportDescriptors);
            }
        }
コード例 #2
0
ファイル: GlimpseCatalog.cs プロジェクト: Antaris/Glimpse.MEF
        /// <summary>
        /// Returns the available exports for the specified import definition.
        /// </summary>
        /// <param name="definition">The import definition.</param>
        /// <returns>The set of matching exports.</returns>
        public override IEnumerable<Tuple<ComposablePartDefinition, ExportDefinition>> GetExports(ImportDefinition definition)
        {
            var definitions = _catalog.GetExports(definition);

            var list = HttpContext.Current.ModelList<ImportDescriptor>("MEF-Imports");

            var model = new ImportDescriptor
                            {
                                Cardinality = definition.Cardinality.ToString(),
                                ContractName = definition.ContractName,
                                Prerequisite = definition.IsPrerequisite,
                                Recomposable = definition.IsRecomposable
                            };

            foreach (var def in definitions)
            {
                var meta = def.Item2.Metadata.Keys
                    .Where(k => k != CreationPolicyTypeName)
                    .ToDictionary(key => key, key => def.Item2.Metadata[key].ToString());

                string policy = null;
                if (def.Item2.Metadata.ContainsKey(CreationPolicyTypeName))
                    policy = def.Item2.Metadata[CreationPolicyTypeName].ToString();

                var export = new ExportDescriptor { CreationPolicy = policy, DisplayName = def.Item1.ToString(), Metadata = meta };

                model.Exports.Add(export);
            }

            list.Add(model);

            return definitions;
        }
コード例 #3
0
        public void GetDescriptor_CycleMetadataCompleted_MethodsReturnExpected()
        {
            ExportDescriptorPromise      promise  = null;
            IDictionary <string, object> metadata = null;

            promise = new ExportDescriptorPromise(new CompositionContract(typeof(int)), "Origin", true, () => Enumerable.Empty <CompositionDependency>(), depdendencies =>
            {
                ExportDescriptor cycleDescriptor = promise.GetDescriptor();
                metadata = cycleDescriptor.Metadata;

                return(ExportDescriptor.Create(Activator, new Dictionary <string, object> {
                    { "key", "value" }
                }));
            });

            // Invoke the GetDescriptor method to start the test.
            Assert.NotNull(promise.GetDescriptor());

            // Make sure all the IDictionary methods complete successfully.
            Assert.Equal("value", metadata["key"]);
            Assert.True(metadata.Contains(new KeyValuePair <string, object>("key", "value")));
            Assert.True(metadata.ContainsKey("key"));
            Assert.False(metadata.IsReadOnly);

            metadata["key"] = "value2";
            Assert.True(metadata.TryGetValue("key", out object value));
            Assert.Equal("value2", value);

            metadata.Add("key2", "value");
            Assert.Equal(2, metadata.Count);

            metadata.Remove("key2");
            Assert.Equal(1, metadata.Count);

            metadata.Add(new KeyValuePair <string, object>("key2", "value"));
            Assert.Equal(2, metadata.Count);

            metadata.Remove(new KeyValuePair <string, object>("key2", "value"));
            Assert.Equal(1, metadata.Count);

            Assert.Equal(1, metadata.Keys.Count);
            Assert.Equal(1, metadata.Values.Count);

            var array = new KeyValuePair <string, object> [2];

            metadata.CopyTo(array, 1);
            Assert.Equal(new KeyValuePair <string, object>[] { default(KeyValuePair <string, object>), new KeyValuePair <string, object>("key", "value2") }, array);

            IEnumerator enumerator = metadata.GetEnumerator();

            Assert.True(enumerator.MoveNext());
            Assert.Equal(new KeyValuePair <string, object>("key", "value2"), enumerator.Current);

            enumerator = ((IEnumerable)metadata).GetEnumerator();
            Assert.True(enumerator.MoveNext());
            Assert.Equal(new KeyValuePair <string, object>("key", "value2"), enumerator.Current);

            metadata.Clear();
            Assert.Equal(0, metadata.Count);
        }
コード例 #4
0
        static ExportDescriptorPromise GetDictionaryDefinition <TKey, TValue>(CompositionContract dictionaryContract, CompositionContract valueContract, DependencyAccessor definitionAccessor, string keyByMetadataName)
        {
            return(new ExportDescriptorPromise(
                       dictionaryContract,
                       typeof(IDictionary <TKey, TValue>).Name,
                       false,
                       () => definitionAccessor.ResolveDependencies("value", valueContract, true),
                       deps => {
                var items = deps.Select(d => Tuple.Create(d.Target.Origin, d.Target.GetDescriptor())).ToArray();
                var isValidated = false;
                return ExportDescriptor.Create((c, o) =>
                {
                    if (!isValidated)
                    {
                        Validate <TKey>(items, keyByMetadataName);
                        isValidated = true;
                    }

                    return items.ToDictionary(
                        item => (TKey)item.Item2.Metadata[keyByMetadataName],
                        item => (TValue)item.Item2.Activator(c, o));
                },
                                               NoMetadata);
            }));
        }
コード例 #5
0
        public override IEnumerable <ExportDescriptorPromise> GetExportDescriptors(CompositionContract contract, DependencyAccessor definitionAccessor)
        {
            if (contract.ContractType.IsAbstract ||
                !contract.ContractType.IsClass ||
                !contract.Equals(new CompositionContract(contract.ContractType)))
            {
                return(NoExportDescriptors);
            }

            if (!definitionAccessor.ResolveDependencies("test", contract, false).Any())
            {
                return(NoExportDescriptors);
            }

            return(new[] { new ExportDescriptorPromise(
                               contract,
                               contract.ContractType.Name,
                               false,
                               NoDependencies,
                               _ => ExportDescriptor.Create((c, o) => {
                    var instance = Activator.CreateInstance(contract.ContractType);
                    if (instance is IDisposable)
                    {
                        c.AddBoundInstance((IDisposable)instance);
                    }
                    return instance;
                }, NoMetadata)) });
        }
コード例 #6
0
        public void Create_Valid_ReturnsExpected(CompositeActivator activator, Dictionary <string, object> metadata)
        {
            ExportDescriptor descriptor = ExportDescriptor.Create(activator, metadata);

            Assert.Same(activator, descriptor.Activator);
            Assert.Same(metadata, descriptor.Metadata);
        }
コード例 #7
0
        static ExportDescriptorPromise[] GetExportFactoryDescriptors <TProduct>(CompositionContract exportFactoryContract, DependencyAccessor definitionAccessor)
        {
            var productContract = exportFactoryContract.ChangeType(typeof(TProduct));
            var boundaries      = new string[0];

            IEnumerable <string> specifiedBoundaries;
            CompositionContract  unwrapped;

            if (exportFactoryContract.TryUnwrapMetadataConstraint(Constants.SharingBoundaryImportMetadataConstraintName, out specifiedBoundaries, out unwrapped))
            {
                productContract = unwrapped.ChangeType(typeof(TProduct));
                boundaries      = (specifiedBoundaries ?? new string[0]).ToArray();
            }

            return(definitionAccessor.ResolveDependencies("product", productContract, false)
                   .Select(d => new ExportDescriptorPromise(
                               exportFactoryContract,
                               Formatters.Format(typeof(ExportFactory <TProduct>)),
                               false,
                               () => new[] { d },
                               _ =>
            {
                var dsc = d.Target.GetDescriptor();
                var da = dsc.Activator;
                return ExportDescriptor.Create((c, o) =>
                {
                    return new ExportFactory <TProduct>(() => {
                        var lifetimeContext = new LifetimeContext(c, boundaries);
                        return Tuple.Create <TProduct, Action>((TProduct)CompositionOperation.Run(lifetimeContext, da), lifetimeContext.Dispose);
                    });
                },
                                               dsc.Metadata);
            }))
                   .ToArray());
        }
コード例 #8
0
        ///<inheritdoc />
        public override IEnumerable <ExportDescriptorPromise> GetExportDescriptors(CompositionContract contract, DependencyAccessor descriptorAccessor)
        {
            if (_loggerFactory != null && _ILoggerType.IsAssignableFrom(contract.ContractType))
            {
                ILogger logger;

                if (contract.ContractType.GenericTypeArguments.Length > 0)
                {
                    logger = CreateLogger(contract.ContractType.GenericTypeArguments.FirstOrDefault());
                }
                else
                {
                    logger = _loggerFactory.CreateLogger(contract.ContractType);
                }

                yield return(new ExportDescriptorPromise(
                                 contract,
                                 contract.ContractType.FullName,
                                 true,
                                 NoDependencies,
                                 dependencies => ExportDescriptor.Create((context, operation) => logger, NoMetadata)));
            }
            else if (_hasInstances)
            {
                foreach (var descriptor in base.GetExportDescriptors(contract, descriptorAccessor))
                {
                    yield return(descriptor);
                }
            }
        }
コード例 #9
0
        public override IEnumerable <ExportDescriptorPromise> GetExportDescriptors(
            CompositionContract contract, DependencyAccessor descriptorAccessor)
        {
            if (_logger.IsEnabled(LogLevel.Debug))
            {
                _logger.LogDebug($"Getting Export Descriptors:"
                                 + $" contractName=[{contract.ContractName}]"
                                 + $" contractType=[{contract.ContractType.FullName}]");
            }

            var svc = _serviceProvider.GetService(contract.ContractType);

            if (svc == null)
            {
                if (_logger.IsEnabled(LogLevel.Debug))
                {
                    _logger.LogDebug($"No DI service found for"
                                     + $" contractType=[{contract.ContractType.FullName}]");
                }
                yield break;
            }

            if (_logger.IsEnabled(LogLevel.Debug))
            {
                _logger.LogDebug($"Resolved DI service for"
                                 + $" contractType=[{contract.ContractType.FullName}]"
                                 + $" service=[{svc}]");
            }

            CompositeActivator ca = (ctx, op) => svc;

            yield return(new ExportDescriptorPromise(contract, ORIGIN_NAME, true,
                                                     NoDependencies, deps => ExportDescriptor.Create(ca, NoMetadata)));
        }
コード例 #10
0
 public override IEnumerable <ExportDescriptorPromise> GetExportDescriptors(CompositionContract contract, DependencyAccessor descriptorAccessor)
 {
     if (IsSupportedContract(contract))
     {
         yield return(new ExportDescriptorPromise(contract, _exportedInstance.ToString(), true, NoDependencies, _ =>
                                                  ExportDescriptor.Create((c, o) => _exportedInstance, Metadata)));
     }
 }
コード例 #11
0
 public override IEnumerable <ExportDescriptorPromise> GetExportDescriptors(CompositionContract contract, DependencyAccessor descriptorAccessor)
 {
     if (contract.ContractType == typeof(T))
     {
         yield return(new ExportDescriptorPromise(contract, string.Empty, true,
                                                  () => Enumerable.Empty <CompositionDependency>(),
                                                  deps => ExportDescriptor.Create((context, operation) => _item, _metadata ?? new Dictionary <string, object>())));
     }
 }
コード例 #12
0
        public void ToString_Invoke_ReturnsExpected()
        {
            var promise = new ExportDescriptorPromise(new CompositionContract(typeof(int)), "Origin", true, () => Enumerable.Empty <CompositionDependency>(), depdendencies =>
            {
                return(ExportDescriptor.Create(Activator, new Dictionary <string, object>()));
            });

            Assert.Equal("Int32 supplied by Origin", promise.ToString());
        }
コード例 #13
0
            public override IEnumerable <ExportDescriptorPromise> GetExportDescriptors(CompositionContract contract, DependencyAccessor descriptorAccessor)
            {
                var target = new ExportDescriptorPromise(new CompositionContract(typeof(int)), "Origin", true, () => Enumerable.Empty <CompositionDependency>(), dependencies =>
                {
                    return(ExportDescriptor.Create(Activator, new Dictionary <string, object>()));
                });

                return(new ExportDescriptorPromise[] { target, target });
            }
コード例 #14
0
        public void Satisfied_NullContract_ThrowsArgumentNullException()
        {
            var descriptor = ExportDescriptor.Create(Activator, new Dictionary <string, object>());
            var target     = new ExportDescriptorPromise(new CompositionContract(typeof(int)), "Origin", true, () => Enumerable.Empty <CompositionDependency>(), dependencies =>
            {
                return(ExportDescriptor.Create(Activator, new Dictionary <string, object>()));
            });

            AssertExtensions.Throws <ArgumentNullException>("contract", () => CompositionDependency.Satisfied(null, target, false, new object()));
        }
コード例 #15
0
        public void Dependencies_GetWhenReturnsNull_ThrowsArgumentNullException()
        {
            var descriptor = ExportDescriptor.Create(Activator, new Dictionary <string, object>());
            var promise    = new ExportDescriptorPromise(new CompositionContract(typeof(int)), "Origin", true, () => null, depdendencies =>
            {
                return(ExportDescriptor.Create(Activator, new Dictionary <string, object>()));
            });

            AssertExtensions.Throws <ArgumentNullException>("source", () => promise.Dependencies);
        }
コード例 #16
0
        public void GetDescriptor_GetWhenNull_ThrowsNullReferenceException()
        {
            var descriptor = ExportDescriptor.Create(Activator, new Dictionary <string, object>());
            var promise    = new ExportDescriptorPromise(new CompositionContract(typeof(int)), "Origin", true, null, dependencies =>
            {
                return(ExportDescriptor.Create(Activator, new Dictionary <string, object>()));
            });

            Assert.Throws <NullReferenceException>(() => promise.GetDescriptor());
        }
コード例 #17
0
        public void GetDescriptor_GetWhenReturnsNull_ThrowsArgumentNullException()
        {
            var descriptor = ExportDescriptor.Create(Activator, new Dictionary <string, object>());
            var promise    = new ExportDescriptorPromise(new CompositionContract(typeof(int)), "Origin", true, () => Enumerable.Empty <CompositionDependency>(), depdendencies =>
            {
                return(null);
            });

            AssertExtensions.Throws <ArgumentNullException>("descriptor", () => promise.GetDescriptor());
        }
コード例 #18
0
        public void GetDescriptor_GetWhenReturnsNull_ThrowsInternalErrorException()
        {
            var descriptor = ExportDescriptor.Create(Activator, new Dictionary <string, object>());
            var promise    = new ExportDescriptorPromise(new CompositionContract(typeof(int)), "Origin", true, () => Enumerable.Empty <CompositionDependency>(), depdendencies =>
            {
                return(null);
            });

            Exception ex = Assert.ThrowsAny <Exception>(() => promise.GetDescriptor());

            Assert.Equal("Microsoft.Internal.Assumes+InternalErrorException", ex.GetType().ToString());
        }
コード例 #19
0
        protected override ExportDescriptor GetExportDescriptor(CompositeActivator partActivator)
        {
            var args = new[] { Expression.Parameter(typeof(LifetimeContext)), Expression.Parameter(typeof(CompositionOperation)) };

            var activator = Expression.Lambda <CompositeActivator>(
                Expression.Property(
                    Expression.Convert(Expression.Call(Expression.Constant(partActivator), ActivatorInvoke, args), _property.DeclaringType),
                    _property),
                args);

            return(ExportDescriptor.Create(activator.Compile(), Metadata));
        }
コード例 #20
0
        public override IEnumerable <ExportDescriptorPromise> GetExportDescriptors(CompositionContract contract, DependencyAccessor descriptorAccessor)
        {
            if (!_services.TryGetValue(contract.ContractType, out var service) &&
                !(contract.ContractType.IsGenericType && contract.ContractType.GetGenericTypeDefinition() is var genericType &&
                  _services.TryGetValue(genericType, out service)))
            {
                yield break;
            }

            yield return(new ExportDescriptorPromise(contract, nameof(ServiceCollectionExportDescriptorProvider),
                                                     service.Lifetime != ServiceLifetime.Transient, () => Array.Empty <CompositionDependency>(),
                                                     _ => ExportDescriptor.Create((_, _) => _serviceProvider.GetService(contract.ContractType),
                                                                                  new Dictionary <string, object>())));
        }
コード例 #21
0
 public override IEnumerable <ExportDescriptorPromise> GetExportDescriptors(
     CompositionContract contract,
     DependencyAccessor descriptorAccessor)
 {
     if (contract.ContractType == ContractType)
     {
         yield return(new ExportDescriptorPromise(
                          contract,
                          contract.ContractType.FullName,
                          false,
                          ExportDescriptorProvider.NoDependencies,
                          dependencies => ExportDescriptor.Create(activator, ExportDescriptorProvider.NoMetadata)));
     }
 }
コード例 #22
0
        public override IEnumerable <ExportDescriptorPromise> GetExportDescriptors(CompositionContract contract, DependencyAccessor definitionAccessor)
        {
            if (!contract.Equals(s_currentScopeContract))
            {
                return(NoExportDescriptors);
            }

            return(new[] { new ExportDescriptorPromise(
                               contract,
                               nameof(CompositionContext),
                               true,
                               NoDependencies,
                               _ => ExportDescriptor.Create((c, o) => c, NoMetadata)) });
        }
コード例 #23
0
        public static IEnumerable <object[]> Oversupplied_TestData()
        {
            yield return(new object[] { Enumerable.Empty <ExportDescriptorPromise>() });

            yield return(new object[] { new ExportDescriptorPromise[] { null } });

            var descriptor = ExportDescriptor.Create(Activator, new Dictionary <string, object>());
            var target     = new ExportDescriptorPromise(new CompositionContract(typeof(int)), "Origin", false, () => Enumerable.Empty <CompositionDependency>(), dependencies =>
            {
                return(ExportDescriptor.Create(Activator, new Dictionary <string, object>()));
            });

            yield return(new object[] { new ExportDescriptorPromise[] { target } });
        }
コード例 #24
0
        public override IEnumerable <ExportDescriptorPromise> GetExportDescriptors(
            CompositionContract contract, DependencyAccessor descriptorAccessor)
        {
            object svc = _serviceProvider.GetService(contract.ContractType);

            if (svc == null)
            {
                yield break;
            }

            object Ca(LifetimeContext ctx, CompositionOperation op) => svc;

            yield return(new ExportDescriptorPromise(contract, OriginName, true,
                                                     NoDependencies, deps => ExportDescriptor.Create(Ca, NoMetadata)));
        }
コード例 #25
0
        public override IEnumerable <ExportDescriptorPromise> GetExportDescriptors(CompositionContract contract, DependencyAccessor descriptorAccessor)
        {
            if (_serviceCollection.SingleOrDefault(x => x.ServiceType == contract.ContractType) is null)
            {
                return(Array.Empty <ExportDescriptorPromise>());
            }

            return(new[]
            {
                new ExportDescriptorPromise(contract, "ServiceProvider", false, NoDependencies,
                                            _ => ExportDescriptor.Create(
                                                (l, o) => _serviceProvider.GetRequiredService(contract.ContractType),
                                                NoMetadata))
            });
        }
コード例 #26
0
ファイル: PrimitiveExport.cs プロジェクト: zqb971/mef
        public ExportDescriptorPromise GetPromise(CompositionContract contract, DependencyAccessor descriptorAccessor)
        {
            var origin = _export.ToString();

            if (_export is ICompositionElement)
            {
                origin = ((ICompositionElement)_export).DisplayName;
            }

            return(new ExportDescriptorPromise(contract, origin, _part.IsShared, () => _part.GetDependencies(descriptorAccessor), d =>
            {
                var partActivator = _part.GetActivator(d);
                CompositeActivator exportActivator = (c, o) => ((ComposablePart)partActivator(c, o)).GetExportedValue(_export);
                return ExportDescriptor.Create(exportActivator, _export.Metadata);
            }));
        }
コード例 #27
0
 private static ExportDescriptorPromise[] GetLazyDefinitions <TValue>(CompositionContract lazyContract, DependencyAccessor definitionAccessor)
 {
     return(definitionAccessor.ResolveDependencies("value", lazyContract.ChangeType(typeof(TValue)), false)
            .Select(d => new ExportDescriptorPromise(
                        lazyContract,
                        Formatters.Format(typeof(Lazy <TValue>)),
                        false,
                        () => new[] { d },
                        _ =>
     {
         var dsc = d.Target.GetDescriptor();
         var da = dsc.Activator;
         return ExportDescriptor.Create((c, o) => new Lazy <TValue>(() => (TValue)CompositionOperation.Run(c, da)), dsc.Metadata);
     }))
            .ToArray());
 }
コード例 #28
0
 public override IEnumerable <ExportDescriptorPromise> GetExportDescriptors(
     CompositionContract contract,
     DependencyAccessor descriptorAccessor)
 {
     if (contract.ContractType == ContractType)
     {
         yield return(new ExportDescriptorPromise(
                          contract,
                          contract.ContractType.FullName,
                          true,
                          ExportDescriptorProvider.NoDependencies,
                          dependencies => ExportDescriptor.Create(
                              (context, operation) => SharedInstance,
                              ExportDescriptorProvider.NoMetadata)));
     }
 }
コード例 #29
0
        static ExportDescriptorPromise GetImportManyDescriptor <TElement>(CompositionContract importManyContract, CompositionContract elementContract, DependencyAccessor definitionAccessor)
        {
            return(new ExportDescriptorPromise(
                       importManyContract,
                       typeof(TElement[]).Name,
                       false,
                       () => definitionAccessor.ResolveDependencies("item", elementContract, true),
                       d =>
            {
                var dependentDescriptors = d
                                           .Select(el => el.Target.GetDescriptor())
                                           .ToArray();

                return ExportDescriptor.Create((c, o) => dependentDescriptors.Select(e => (TElement)e.Activator(c, o)).ToArray(), NoMetadata);
            }));
        }
コード例 #30
0
        public void GetDescriptor_CycleMetadataBroken_HasExpectedProperties()
        {
            ExportDescriptorPromise promise         = null;
            ExportDescriptor        cycleDescriptor = null;

            promise = new ExportDescriptorPromise(new CompositionContract(typeof(int)), "Origin", true, () => Enumerable.Empty <CompositionDependency>(), depdendencies =>
            {
                cycleDescriptor = promise.GetDescriptor();
                return(ExportDescriptor.Create(Activator, new Dictionary <string, object> {
                    { "key", "value" }
                }));
            });

            ExportDescriptor descriptor = promise.GetDescriptor();

            Assert.Same(descriptor.Activator, cycleDescriptor.Activator);
            Assert.Same(descriptor.Metadata, cycleDescriptor.Metadata);
        }
コード例 #31
0
        public void Satisfied_Invoke_ReturnsExpected()
        {
            var contract   = new CompositionContract(typeof(int));
            var descriptor = ExportDescriptor.Create(Activator, new Dictionary <string, object>());
            var target     = new ExportDescriptorPromise(new CompositionContract(typeof(int)), "Origin", false, () => Enumerable.Empty <CompositionDependency>(), dependencies =>
            {
                return(ExportDescriptor.Create(Activator, new Dictionary <string, object>()));
            });

            CompositionDependency dependency = CompositionDependency.Satisfied(contract, target, true, "Site");

            Assert.Same(contract, dependency.Contract);
            Assert.Equal("Site", dependency.Site);
            Assert.Same(target, dependency.Target);
            Assert.True(dependency.IsPrerequisite);

            Assert.Equal("'Site' on contract 'Int32' supplied by Origin", dependency.ToString());
        }
コード例 #32
0
        /// <summary>
        /// Gets the catalog descriptors for the specified catalog.
        /// </summary>
        /// <param name="catalog">The part catalog.</param>
        /// <returns>A set of catalog descriptors.</returns>
        private static IEnumerable<CatalogDescriptor> GetCatalogDescriptors(ComposablePartCatalog catalog)
        {
            var result = new List<CatalogDescriptor>();
            CatalogDescriptor descriptor = null;

            var glimpseCatalog = catalog as GlimpseCatalog;
            if (glimpseCatalog != null)
            {
                result.AddRange(GetCatalogDescriptors(glimpseCatalog.Catalog));
                return result;
            }

            var aggregateCatalog = catalog as AggregateCatalog;
            if (aggregateCatalog != null)
            {
                descriptor = new CatalogDescriptor() { Type = aggregateCatalog.GetType().Name, IsAggregate = true};

                foreach (var child in aggregateCatalog.Catalogs)
                    descriptor.ChildCatalogs.AddRange(GetCatalogDescriptors(child));

                result.Add(descriptor);
                return result;
            }

            descriptor = new CatalogDescriptor() { Type = catalog.GetType().Name };
            descriptor.Properties = catalog.GetProperties();

            foreach (var part in catalog.Parts)
            {
                foreach (var def in part.ExportDefinitions)
                {
                    var meta = def.Metadata.Keys
                        .Where(k => k != CreationPolicyTypeName)
                        .ToDictionary(key => key, key => def.Metadata[key].ToString());

                    string policy = null;
                    if (def.Metadata.ContainsKey(CreationPolicyTypeName))
                        policy = def.Metadata[CreationPolicyTypeName].ToString();

                    var export = new ExportDescriptor { CreationPolicy = policy, DisplayName = part.ToString(), Metadata = meta };

                    descriptor.Parts.Add(export);
                }
            }

            result.Add(descriptor);

            return result;
        }