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; }