public void RegisterConventions(IConventionsBuilder builder, IEnumerable<TypeInfo> candidateTypes)
 {
     builder
         .ForTypesDerivedFrom(typeof(ICalculator))
         .Export(
             b => b.AsContractType(typeof(ICalculator))
                   .AddMetadata("type", t => t.Name.StartsWith("Scientific") ? "Scientific" : "Classical"))
         .Shared();
 }
        /// <summary>
        /// Tries to get the part builder.
        /// </summary>
        /// <param name="serviceContractMetadata">The service contract metadata.</param>
        /// <param name="serviceContract">The service contract.</param>
        /// <param name="conventions">The conventions.</param>
        /// <param name="typeInfos">The type infos.</param>
        /// <returns>
        /// The part builder or <c>null</c>.
        /// </returns>
        private IPartConventionsBuilder TryGetPartBuilder(
            AppServiceContractAttribute serviceContractMetadata,
            TypeInfo serviceContract,
            IConventionsBuilder conventions,
            IEnumerable<TypeInfo> typeInfos)
        {
            var serviceContractType = serviceContract.AsType();

            if (serviceContract.IsGenericTypeDefinition)
            {
                // if there is non-generic service contract with the same full name
                // then add just the conventions for the derived types.
                return conventions.ForTypesMatching(t => this.MatchOpenGenericContractType(t, serviceContractType));
            }

            if (serviceContractMetadata.AllowMultiple)
            {
                // if the service contract metadata allows multiple service registrations
                // then add just the conventions for the derived types.
                return conventions.ForTypesDerivedFrom(serviceContractType);
            }

            var parts =
                typeInfos.Where(
                    ti =>
                    serviceContract.IsAssignableFrom(ti) && ti.IsClass && !ti.IsAbstract
                    && ti.GetCustomAttribute<ExcludeFromCompositionAttribute>() == null).ToList();
            if (parts.Count == 1)
            {
                return conventions.ForType(parts[0].AsType());
            }

            if (parts.Count > 1)
            {
                var overrideChain =
                    parts.ToDictionary(
                        ti => ti,
                        ti =>
                        ti.GetCustomAttribute<OverridePriorityAttribute>() ?? new OverridePriorityAttribute(Priority.Normal))
                        .OrderBy(item => item.Value.Value)
                        .ToList();

                var selectedPart = overrideChain[0].Key;
                if (overrideChain[0].Value.Value == overrideChain[1].Value.Value)
                {
                    throw new InvalidOperationException(
                        string.Format(
                            Strings.AmbiguousOverrideForAppServiceContract,
                            serviceContract,
                            selectedPart,
                            string.Join(", ", overrideChain.Select(item => item.Key.ToString() + ":" + item.Value.Value))));
                }

                return conventions.ForType(selectedPart.AsType());
            }

            return null;
        }