private void DoCallStObjConstruct(IActivityMonitor monitor, BuildValueCollector valueCollector, IStObjValueResolver?valueResolver, MethodInfo stobjConstruct, IReadOnlyList <MutableParameter> mutableParameters) { object?[] parameters = new object[mutableParameters.Count]; int i = 0; foreach (MutableParameter t in mutableParameters) { // We inject our "setup monitor" for IActivityMonitor parameter type. if (t.IsSetupLogger) { t.SetParameterValue(monitor); t.BuilderValueIndex = Int32.MaxValue; } else { MutableItem?resolved = null; if (t.Value == System.Type.Missing) { // Parameter reference have already been resolved as dependencies for graph construction since // no Value has been explicitly set for the parameter. resolved = t.CachedResolvedStObj; if (resolved != null) { Debug.Assert(resolved.InitialObject != System.Type.Missing); t.SetParameterValue(resolved.InitialObject); } } if (valueResolver != null) { valueResolver.ResolveParameterValue(monitor, t); } if (t.Value == System.Type.Missing && !t.IsRealParameterOptional) { if (!t.IsOptional) { // By throwing an exception here, we stop the process and avoid the construction // of an invalid object graph... // This behavior (FailFastOnFailureToResolve) may be an option once. For the moment: log the error. monitor.Fatal($"{t}: Unable to resolve non optional. Attempting to use a default value to continue the setup process in order to detect other errors."); } Debug.Assert(t.Type != null); t.SetParameterValue(t.Type.IsValueType ? Activator.CreateInstance(t.Type) : null); } if (resolved != null && t.Value == resolved.InitialObject) { t.BuilderValueIndex = -(resolved.IndexOrdered + 1); } else { t.BuilderValueIndex = valueCollector.RegisterValue(t.Value); } } parameters[i++] = t.Value; } stobjConstruct.Invoke(_leafData.StructuredObject, parameters); }
internal PropertySetter(PropertyInfo p, object?o, BuildValueCollector valueCollector) { Property = p; Value = o; if (o is MutableItem) { IndexValue = -1; } else { IndexValue = valueCollector.RegisterValue(o); } }