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