internal object ConstructType( Type implementationType, ConstructorInfo constructor, DependencyContainerResolveOptions options = null) { var typeToConstruct = implementationType; if (constructor == null) { // Try and get the best constructor that we can construct // if we can't construct any then get the constructor // with the least number of parameters so we can throw a meaningful // resolve exception constructor = GetBestConstructor(typeToConstruct, options) ?? GetTypeConstructors(typeToConstruct).LastOrDefault(); } if (constructor == null) { throw new DependencyContainerResolutionException(typeToConstruct); } var ctorParams = constructor.GetParameters(); var args = new object[ctorParams.Length]; for (var parameterIndex = 0; parameterIndex < ctorParams.Length; parameterIndex++) { var currentParam = ctorParams[parameterIndex]; try { args[parameterIndex] = options?.ConstructorParameters.GetValueOrDefault(currentParam.Name, ResolveInternal(new DependencyContainer.TypeRegistration(currentParam.ParameterType), options.Clone())); } catch (DependencyContainerResolutionException ex) { // If a constructor parameter can't be resolved // it will throw, so wrap it and throw that this can't // be resolved. throw new DependencyContainerResolutionException(typeToConstruct, ex); } catch (Exception ex) { throw new DependencyContainerResolutionException(typeToConstruct, ex); } } try { return(CreateObjectConstructionDelegateWithCache(constructor).Invoke(args)); } catch (Exception ex) { throw new DependencyContainerResolutionException(typeToConstruct, ex); } }
private bool CanConstruct( ConstructorInfo ctor, DependencyContainerResolveOptions options) { foreach (var parameter in ctor.GetParameters()) { if (string.IsNullOrEmpty(parameter.Name)) { return(false); } var isParameterOverload = options.ConstructorParameters.ContainsKey(parameter.Name); if (parameter.ParameterType.IsPrimitive && !isParameterOverload) { return(false); } if (!isParameterOverload && !CanResolve(new DependencyContainer.TypeRegistration(parameter.ParameterType), options.Clone())) { return(false); } } return(true); }
internal bool CanResolve( DependencyContainer.TypeRegistration registration, DependencyContainerResolveOptions options = null) { if (options == null) { options = DependencyContainerResolveOptions.Default; } var checkType = registration.Type; var name = registration.Name; if (TryGetValue(new DependencyContainer.TypeRegistration(checkType, name), out var factory)) { if (factory.AssumeConstruction) { return(true); } if (factory.Constructor == null) { return(GetBestConstructor(factory.CreatesType, options) != null); } return(CanConstruct(factory.Constructor, options)); } // Fail if requesting named resolution and settings set to fail if unresolved // Or bubble up if we have a parent if (!string.IsNullOrEmpty(name) && options.NamedResolutionFailureAction == DependencyContainerNamedResolutionFailureAction.Fail) { return(_dependencyContainer.Parent?.RegisteredTypes.CanResolve(registration, options.Clone()) ?? false); } // Attempted unnamed fallback container resolution if relevant and requested if (!string.IsNullOrEmpty(name) && options.NamedResolutionFailureAction == DependencyContainerNamedResolutionFailureAction.AttemptUnnamedResolution) { if (TryGetValue(new DependencyContainer.TypeRegistration(checkType), out factory)) { if (factory.AssumeConstruction) { return(true); } return(GetBestConstructor(factory.CreatesType, options) != null); } } // Check if type is an automatic lazy factory request or an IEnumerable<ResolveType> if (IsAutomaticLazyFactoryRequest(checkType) || registration.Type.IsIEnumerable()) { return(true); } // Attempt unregistered construction if possible and requested // If we cant', bubble if we have a parent if ((options.UnregisteredResolutionAction == DependencyContainerUnregisteredResolutionAction.AttemptResolve) || (checkType.IsGenericType && options.UnregisteredResolutionAction == DependencyContainerUnregisteredResolutionAction.GenericsOnly)) { return((GetBestConstructor(checkType, options) != null) || (_dependencyContainer.Parent?.RegisteredTypes.CanResolve(registration, options.Clone()) ?? false)); } // Bubble resolution up the container tree if we have a parent return(_dependencyContainer.Parent != null && _dependencyContainer.Parent.RegisteredTypes.CanResolve(registration, options.Clone())); }