public static void Inject(IBuildContext context, object obj) { FieldInfo[] fields = obj.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic); foreach (FieldInfo field in fields) { object[] attrs = field.GetCustomAttributes(typeof(InjectContextAttribute), true); if (attrs.Length == 0) continue; InjectContextAttribute attr = attrs[0] as InjectContextAttribute; if (attr == null || attr.Usage == ContextUsage.Out) continue; object injectionObject; if (field.FieldType == typeof(IBuildContext)) injectionObject = context; else if (!attr.Optional) injectionObject = context.GetContextObject(field.FieldType); else { IContextObject contextObject; context.TryGetContextObject(field.FieldType, out contextObject); injectionObject = contextObject; } field.SetValue(obj, injectionObject); } }
/// <summary> /// Basic run implementation that takes a set of tasks, a context, and runs returning the build results. /// <seealso cref="IBuildTask"/>, <seealso cref="IBuildContext"/>, and <seealso cref="ReturnCode"/> /// </summary> /// <param name="pipeline">The set of build tasks to run.</param> /// <param name="context">The build context to use for this run.</param> /// <returns>Return code with status information about success or failure causes.</returns> public static ReturnCode Run(IList <IBuildTask> pipeline, IBuildContext context) { // Avoid throwing exceptions in here as we don't want them bubbling up to calling user code if (pipeline == null) { BuildLogger.LogException(new ArgumentNullException("pipeline")); return(ReturnCode.Exception); } // Avoid throwing exceptions in here as we don't want them bubbling up to calling user code if (context == null) { BuildLogger.LogException(new ArgumentNullException("context")); return(ReturnCode.Exception); } IProgressTracker tracker; if (context.TryGetContextObject(out tracker)) { tracker.TaskCount = pipeline.Count; } context.TryGetContextObject(out IBuildLogger logger); foreach (IBuildTask task in pipeline) { { try { if (!tracker.UpdateTaskUnchecked(task.GetType().Name.HumanReadable())) { return(ReturnCode.Canceled); } ContextInjector.Inject(context, task); ReturnCode result; using (logger.ScopedStep(LogLevel.Info, task.GetType().Name)) result = task.Run(); if (result < ReturnCode.Success) { return(result); } ContextInjector.Extract(context, task); } catch (Exception e) { BuildLogger.LogError("Build Task {0} failed with exception:\n{1}\n{2}", task.GetType().Name, e.Message, e.StackTrace); return(ReturnCode.Exception); } } } return(ReturnCode.Success); }
/// <summary> /// Basic run implementation that takes a set of tasks, a context, and runs returning the build results. /// <seealso cref="IBuildTask"/>, <seealso cref="IBuildContext"/>, and <seealso cref="ReturnCode"/> /// </summary> /// <param name="pipeline">The set of build tasks to run.</param> /// <param name="context">The build context to use for this run.</param> /// <returns>Return code with status information about success or failure causes.</returns> public static ReturnCode Run(IList <IBuildTask> pipeline, IBuildContext context) { // Avoid throwing exceptions in here as we don't want them bubbling up to calling user code if (pipeline == null) { BuildLogger.LogException(new ArgumentNullException("pipeline")); return(ReturnCode.Exception); } // Avoid throwing exceptions in here as we don't want them bubbling up to calling user code if (context == null) { BuildLogger.LogException(new ArgumentNullException("context")); return(ReturnCode.Exception); } IProgressTracker tracker; if (context.TryGetContextObject(out tracker)) { tracker.TaskCount = pipeline.Count; } foreach (IBuildTask task in pipeline) { try { if (!tracker.UpdateTaskUnchecked(task.GetType().Name.HumanReadable())) { return(ReturnCode.Canceled); } ContextInjector.Inject(context, task); var result = task.Run(); if (result < ReturnCode.Success) { return(result); } ContextInjector.Extract(context, task); } catch (Exception e) { BuildLogger.LogException(e); return(ReturnCode.Exception); } } return(ReturnCode.Success); }