public static bool TryConstruct( Type targetType, out object service, ServiceConstructorRequest request, IServiceRegistrationProvider serviceProvider, Func <Type, object> instanceProvider = null, bool tryConstructArguments = false, bool?requireConstructorAttributes = null, IReadOnlyCollection <Type> constructorAttributeTypes = null) { if (targetType == null) { throw new ArgumentNullException(nameof(targetType)); } if (request == null) { throw new ArgumentNullException(nameof(request)); } if (serviceProvider == null) { throw new ArgumentNullException(nameof(serviceProvider)); } if ((constructorAttributeTypes == null) || (constructorAttributeTypes.Count == 0)) { constructorAttributeTypes = new[] { typeof(ServiceProviderConstructorAttribute) } } ; if (request.ConstructingTypes.Contains(targetType)) { request.TraceStack.Add( "Found a recursive constructor dependency" + $": '{targetType.GetFriendlyFullName()}'" + " ... cannot continue."); service = null; return(false); } request.ConstructingTypes.Add(targetType); request.Logger.Verbose("Constructing {0}.", targetType.GetFriendlyFullName()); if (ServiceConstructorMethods.invokeMember( ServiceConstructorMethods.findConstructors( targetType, requireConstructorAttributes, constructorAttributeTypes, request.TraceStack), false, null, out service, request, serviceProvider, instanceProvider, tryConstructArguments, requireConstructorAttributes, constructorAttributeTypes, false)) { request.Logger.Verbose( "Construct result for '{0}' is true: '{1}'.", targetType.GetFriendlyFullName(), service.GetType().GetFriendlyFullName()); request.ConstructingTypes.Remove(targetType); return(true); } request.Logger.Warning("Construct result for '{0}' is false.", targetType.GetFriendlyFullName()); request.ConstructingTypes.Remove(targetType); return(false); }
private static bool invokeMember( IEnumerable <MethodBase> members, bool isMethod, object methodTarget, out object newInstance, ServiceConstructorRequest request, IServiceRegistrationProvider serviceProvider, Func <Type, object> instanceProvider, bool tryConstructArguments, bool?requireConstructorAttributes, IReadOnlyCollection <Type> constructorAttributeTypes, bool isRecursed) { newInstance = null; bool success = false; foreach (MethodBase methodBase in members) { ParameterInfo[] parameters = methodBase.GetParameters(); if (parameters.Length == 0) { success = isMethod ? ServiceConstructorMethods.tryInvokeMethod( methodTarget, (MethodInfo)methodBase, new object[0], request.TraceStack) : ServiceConstructorMethods.tryInvokeConstructor( (ConstructorInfo)methodBase, new object[0], out newInstance, request.TraceStack); break; } List <object> arguments = new List <object>(parameters.Length); foreach (ParameterInfo parameterInfo in parameters) { if (ServiceConstructorMethods.tryResolve( parameterInfo.ParameterType, out object parameterResult, request, serviceProvider, instanceProvider, !tryConstructArguments)) { arguments.Add(parameterResult); continue; } if (tryConstructArguments) { if (request.ConstructingTypes.Contains(parameterInfo.ParameterType)) { request.TraceStack.Add( "Found a recursive constructor dependency" + $": '{parameterInfo.ParameterType.GetFriendlyFullName()}'" + " ... cannot continue."); break; } request.ConstructingTypes.Add(parameterInfo.ParameterType); bool argumentSuccess = ServiceConstructorMethods.invokeMember( ServiceConstructorMethods.findConstructors( parameterInfo.ParameterType, requireConstructorAttributes, constructorAttributeTypes, request.TraceStack), false, null, out object argumentResult, request, serviceProvider, instanceProvider, true, requireConstructorAttributes, constructorAttributeTypes, true); request.ConstructingTypes.Remove(parameterInfo.ParameterType); if (argumentSuccess) { arguments.Add(argumentResult); continue; } } if (parameterInfo.HasDefaultValue) { request.TraceStack.Add( $"Parameter '{parameterInfo.ParameterType.GetFriendlyFullName()}' has default value."); arguments.Add(parameterInfo.DefaultValue); } else { break; } } if ((arguments.Count != parameters.Length) || (isMethod ? !ServiceConstructorMethods.tryInvokeMethod( methodTarget, (MethodInfo)methodBase, arguments.ToArray(), request.TraceStack) : !ServiceConstructorMethods.tryInvokeConstructor( (ConstructorInfo)methodBase, arguments.ToArray(), out newInstance, request.TraceStack))) { continue; } request.Dependencies.TryAddRange( methodBase.DeclaringType, parameters.Select(parameter => parameter.ParameterType)); success = true; break; } if (isRecursed) { return(success); } if (success) { if (request.Logger.IsVerbose()) { request.Logger.Verbose(GetTraceMessage()); } } else { if (request.Logger.IsInfo()) { request.Logger.Info(GetTraceMessage()); } } string GetTraceMessage() { string separator = $"{Environment.NewLine} "; StringBuilder sb = request.TraceStack.ToConcatenatedString(null, separator); if (sb.Length != 0) { sb.Insert(0, " "); } return(sb.ToString()); } return(success); }