private void ApplySelectors(HashSet <ImplementationType> implementations, ContainerService.Builder builder) { if (builder.Configuration != ServiceConfiguration.empty) { return; } if (implementationSelectors.Count == 0) { return; } var selectorDecisions = new List <ImplementationSelectorDecision>(); var typesArray = implementations.Select(x => x.type).ToArray(); foreach (var s in implementationSelectors) { s(builder.Type, typesArray, selectorDecisions); } foreach (var decision in selectorDecisions) { var item = new ImplementationType { type = decision.target, comment = decision.comment, accepted = decision.action == ImplementationSelectorDecision.Action.Include }; implementations.Replace(item); } }
private HashSet <ImplementationType> GetImplementationTypes(ContainerService.Builder builder) { var result = new HashSet <ImplementationType>(); var candidates = builder.Configuration.ImplementationTypes ?? containerContext.typesList.InheritorsOf(builder.Type.GetDefinition()); var implementationTypesAreExplicitlyConfigured = builder.Configuration.ImplementationTypes != null; foreach (var implType in candidates) { if (!implementationTypesAreExplicitlyConfigured) { var configuration = GetConfiguration(implType, builder.Context); if (configuration.IgnoredImplementation || implType.IsDefined("IgnoredImplementationAttribute")) { result.Add(new ImplementationType { type = implType, comment = "IgnoredImplementation", accepted = false }); } } if (!implType.IsGenericType) { if (!builder.Type.IsGenericType || builder.Type.IsAssignableFrom(implType)) { result.Add(ImplementationType.Accepted(implType)); } } else if (!implType.ContainsGenericParameters) { result.Add(ImplementationType.Accepted(implType)); } else { var mapped = containerContext.genericsAutoCloser.AutoCloseDefinition(implType); foreach (var type in mapped) { if (builder.Type.IsAssignableFrom(type)) { result.Add(ImplementationType.Accepted(type)); } } if (builder.Type.IsGenericType) { var implInterfaces = implType.ImplementationsOf(builder.Type.GetGenericTypeDefinition()); foreach (var implInterface in implInterfaces) { var closed = implType.TryCloseByPattern(implInterface, builder.Type); if (closed != null) { result.Add(ImplementationType.Accepted(closed)); } } } if (builder.Arguments == null) { continue; } var serviceConstructor = implType.GetConstructor(); if (!serviceConstructor.isOk) { continue; } foreach (var formalParameter in serviceConstructor.value.GetParameters()) { if (!formalParameter.ParameterType.ContainsGenericParameters) { continue; } ValueWithType parameterValue; if (!builder.Arguments.TryGet(formalParameter.Name, out parameterValue)) { continue; } var parameterType = parameterValue.value == null ? parameterValue.type : parameterValue.value.GetType(); var implInterfaces = formalParameter.ParameterType.IsGenericParameter ? new List <Type>(1) { parameterType } : parameterType.ImplementationsOf(formalParameter.ParameterType.GetGenericTypeDefinition()); foreach (var implInterface in implInterfaces) { var closedItem = implType.TryCloseByPattern(formalParameter.ParameterType, implInterface); if (closedItem != null) { result.Add(ImplementationType.Accepted(closedItem)); } } } } } return(result); }