/// <summary> /// Gets a Dictionary of errors and their corresponding types to help diagnose possible issues /// that resulted in the ContainerResolutionException. /// </summary> /// <returns>A <see cref="Dictionary{Type, Exception}"/> mapping types that encountered given exceptions in the resolution process.</returns> public ContainerResolutionErrorCollection GetErrors() { var errors = new ContainerResolutionErrorCollection(); if (IsKnownIssue) { return(errors); } var implementingType = TryFindImplementingType(); if (implementingType is null) { errors.Add(ServiceType, new ContainerResolutionException(ServiceType, MissingRegistration)); return(errors); } else if (implementingType.IsAbstract) { errors.Add(ServiceType, new ContainerResolutionException(implementingType, CannotResolveAbstractType)); } PopulateErrors(implementingType, ref errors); return(errors); }
private static void PopulateErrors(Type implementingType, ref ContainerResolutionErrorCollection errors) { var ctors = implementingType.GetConstructors(); if (ctors.Length > 1) { errors.Add(implementingType, new ContainerResolutionException(implementingType, MultipleConstructors)); } else if (ctors.Length == 0) { errors.Add(implementingType, new ContainerResolutionException(implementingType, NoPublicConstructors)); return; } var ctor = ctors.OrderByDescending(x => x.GetParameters().Length).FirstOrDefault(); var parameters = ctor?.GetParameters(); var parameterInstances = new List <object>(); var container = ContainerLocator.Current; if (parameters != null) { foreach (var parameter in parameters) { try { var parameterImplementingType = container.GetRegistrationType(parameter.ParameterType); if (parameterImplementingType is null) { throw new ContainerResolutionException(parameter.ParameterType, MissingRegistration); } var instance = container.Resolve(parameter.ParameterType); parameterInstances.Add(instance); } catch (Exception ex) { // TODO: Add Exceptions Extensions lookup here to get root Exception errors.Add(parameter.ParameterType, ex); if (ex is ContainerResolutionException { IsKnownIssue: false } cre) { foreach (var subError in cre.GetErrors()) { errors.Add(subError.Key, subError.Value); } } } } // Return if we had an error with any children if (parameters.Length != parameterInstances.Count) { return; } } try { // We generally expect some sort of InvocationException Exception here... ctor?.Invoke(parameterInstances.ToArray()); // If we managed to create an instance for every parameter and the // constructor didn't throw an exception when activating the instance // we really aren't sure what allowed us to get here... throw new ContainerResolutionException(implementingType, UnknownError); } catch (TargetInvocationException tie) { errors.Add(implementingType, tie); if (tie.InnerException != null) { errors.Add(implementingType, tie.InnerException); } } catch (Exception ex) { errors.Add(implementingType, ex); } }