public static bool CanSpecialize(IDictionary <string, object?> partMetadata, Type[] specialization)
        {
            int partArity = partMetadata.GetValue <int>(CompositionConstants.GenericPartArityMetadataName);

            if (partArity != specialization.Length)
            {
                return(false);
            }

            object[]? genericParameterConstraints = partMetadata.GetValue <object[]>(CompositionConstants.GenericParameterConstraintsMetadataName);
            GenericParameterAttributes[]? genericParameterAttributes = partMetadata.GetValue <GenericParameterAttributes[]>(CompositionConstants.GenericParameterAttributesMetadataName);

            // if no constraints and attributes been specifed, anything can be created
            if ((genericParameterConstraints == null) && (genericParameterAttributes == null))
            {
                return(true);
            }

            if ((genericParameterConstraints != null) && (genericParameterConstraints.Length != partArity))
            {
                return(false);
            }

            if ((genericParameterAttributes != null) && (genericParameterAttributes.Length != partArity))
            {
                return(false);
            }

            for (int i = 0; i < partArity; i++)
            {
                if (!GenericServices.CanSpecialize(
                        specialization[i],
                        (genericParameterConstraints ![i] as Type[]).CreateTypeSpecializations(specialization),
 private string Translate(string originalValue, int[]?genericParametersOrder)
 {
     if (genericParametersOrder != null)
     {
         string[] specializationIdentities = GenericServices.Reorder(_specializationIdentities, genericParametersOrder);
         return(string.Format(CultureInfo.InvariantCulture, originalValue, specializationIdentities));
     }
     else
     {
         return(Translate(originalValue));
     }
 }
 private IEnumerable <Type[]> GetCandidateParameters(Type[] genericParameters)
 {
     // we iterate over all exports and find only generic ones. Assuming the arity matches, we reorder the original parameters
     foreach (ExportDefinition export in ExportDefinitionsInternal)
     {
         var genericParametersOrder = export.Metadata.GetValue <int[]>(CompositionConstants.GenericExportParametersOrderMetadataName);
         if ((genericParametersOrder != null) && (genericParametersOrder.Length == genericParameters.Length))
         {
             yield return(GenericServices.Reorder(genericParameters, genericParametersOrder));
         }
     }
 }
        private IDictionary <string, object?> TranslateImportMetadata(ContractBasedImportDefinition originalImport)
        {
            int[]? importParametersOrder = originalImport.Metadata.GetValue <int[]>(CompositionConstants.GenericImportParametersOrderMetadataName);
            if (importParametersOrder != null)
            {
                Dictionary <string, object?> metadata = new Dictionary <string, object?>(originalImport.Metadata, StringComparers.MetadataKeyNames);

                // Get the newly re-qualified name of the generic contract and the subset of applicable types from the specialization
                metadata[CompositionConstants.GenericContractMetadataName]   = GenericServices.GetGenericName(originalImport.ContractName, importParametersOrder, _specialization.Length);
                metadata[CompositionConstants.GenericParametersMetadataName] = GenericServices.Reorder(_specialization, importParametersOrder);
                metadata.Remove(CompositionConstants.GenericImportParametersOrderMetadataName);

                return(metadata.AsReadOnly());
            }
            else
            {
                return(originalImport.Metadata);
            }
        }