/// <summary>
        /// Adds the composition metadata.
        /// </summary>
        /// <param name="builder">The builder.</param>
        /// <param name="attributeTypes">The attribute types.</param>
        private void AddCompositionMetadata(IExportConventionsBuilder builder, Type[] attributeTypes)
        {
            if (attributeTypes == null || attributeTypes.Length == 0)
            {
                return;
            }

            foreach (var attributeType in attributeTypes)
            {
                var attrType = attributeType;
                builder.AddMetadata(
                    this.GetMetadataNameFromAttributeType(attributeType),
                    t => this.GetMetadataValueFromAttribute(t, attrType));
            }
        }
 /// <summary>
 /// Configures the export.
 /// </summary>
 /// <param name="serviceContract">The service contract.</param>
 /// <param name="exportBuilder">The export builder.</param>
 /// <param name="exportedContractType">Type of the exported contract.</param>
 /// <param name="metadataAttributes">The metadata attributes.</param>
 private void ConfigureExport(TypeInfo serviceContract, IExportConventionsBuilder exportBuilder, Type exportedContractType, Type[] metadataAttributes)
 {
     exportBuilder.AsContractType(exportedContractType);
     this.AddCompositionMetadata(exportBuilder, metadataAttributes);
     this.AddCompositionMetadataForGenerics(exportBuilder, serviceContract);
 }
        /// <summary>
        /// Adds the composition metadata.
        /// </summary>
        /// <param name="builder">The builder.</param>
        /// <param name="serviceContract">The service contract.</param>
        private void AddCompositionMetadataForGenerics(IExportConventionsBuilder builder, TypeInfo serviceContract)
        {
            if (!serviceContract.IsGenericTypeDefinition)
            {
                return;
            }

            var serviceContractType = serviceContract.AsType();
            var genericTypeParameters = serviceContract.GenericTypeParameters;
            for (var i = 0; i < genericTypeParameters.Length; i++)
            {
                var genericTypeParameter = genericTypeParameters[i];
                var position = i;
                builder.AddMetadata(
                    this.GetMetadataNameFromGenericTypeParameter(genericTypeParameter),
                    t => this.GetMetadataValueFromGenericParameter(t, position, serviceContractType));
            }
        }
        /// <summary>
        /// Adds the composition metadata.
        /// </summary>
        /// <param name="builder">The builder.</param>
        /// <param name="serviceImplementationType">Type of the service implementation.</param>
        /// <param name="attributeTypes">The attribute types.</param>
        private void AddCompositionMetadata(IExportConventionsBuilder builder, Type serviceImplementationType, Type[] attributeTypes)
        {
            // add the service type.
            builder.AddMetadata(nameof(AppServiceMetadata.AppServiceImplementationType), t => serviceImplementationType ?? t ?? typeof(Undefined));

            // add the rest of the metadata indicated by the attributes.
            if (attributeTypes == null || attributeTypes.Length == 0)
            {
                return;
            }

            foreach (var attributeType in attributeTypes)
            {
                var attrType = attributeType;
                builder.AddMetadata(
                    GetMetadataNameFromAttributeType(attrType),
                    t => GetMetadataValueFromAttribute(t, attrType));
            }
        }