/// <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; }
/// <summary> /// Gets metadata attributes. /// </summary> /// <param name="contractAttribute">The contract attribute.</param> /// <returns> /// An array of type. /// </returns> private Type[] GetMetadataAttributes(AppServiceContractAttribute contractAttribute) { if (contractAttribute.MetadataAttributes == null || contractAttribute.MetadataAttributes.Length == 0) { return DefaultMetadataAttributes; } var attrs = contractAttribute.MetadataAttributes.ToList(); foreach (var attr in DefaultMetadataAttributes) { if (!attrs.Contains(attr)) { attrs.Add(attr); } } return attrs.ToArray(); }