using System.Collections.Generic;
using System.Collections.ObjectModel;
public static void Main()
Console.WriteLine("Hello World");
public sealed class NoticeOfViolationLettersFactory : IWorkflowFactory<NoticeOfViolationLettersWorkflow>
public interface IWorkflowFactory
public sealed class NoticeOfViolationLettersProcess : Process
public string Name => "Notice of Violation Letters";
public string Description =>
"Generates various letters to constituents who are in violation of something.";
public NoticeOfViolationLettersProcess(IStage generateLettersStage,
IStage generateBatchPdfStage,
IStage uploadPdfForPrintingStage,
IStage archiveLettersStage)
stages.Add(generateLettersStage);
stages.Add(generateBatchPdfStage);
stages.Add(uploadPdfForPrintingStage);
stages.Add(archiveLettersStage);
sealed class GenerateLettersStage : IStage
readonly List<ITask> tasks = new List<ITask>();
public ReadOnlyCollection<ITask> Stages => tasks.AsReadOnly();
GenerateLettersStage(ITask queryBridgeData)
if (queryBridgeData == null)
throw new ArgumentNullException(nameof(queryBridgeData));
tasks.Add(queryBridgeData);
sealed class QueryBridgeData : ITask
sealed class GeneratePDFs : ITask
sealed class ArchivePDFs : ITask
readonly ITaskContext taskContext;
public ArchivePDFs(ITaskContext taskContext)
throw new ArgumentNullException(nameof(taskContext));
this.taskContext = taskContext;
var pdfs = Directory.GetFiles(taskContext.CurrentWorkspace, "*.pdf");
var pdfsArtifact = new FileCollectionArtifact(pdfs);
taskContext.PublishArtifact(pdfsArtifact);
#endregion Example Plugin
public abstract class Process
protected readonly List<IStage> stages = new List<IStage>();
public ReadOnlyCollection<IStage> Stages => stages.AsReadOnly();
public interface IProcess
string Description { get; }
ReadOnlyCollection<ITask> Stages { get; }
public interface IConditionalTask : ITask
bool TaskShouldExecute(ITaskContext taskContext);
public interface IArtifact
string RelativeDirectory { get; }
public sealed class FileArtifact : IArtifact
public FileArtifact(string fileName, string relativeDirectory, string workspaceRootDir)
throw new ArgumentNullException(nameof(fileName));
if (String.IsNullOrWhiteSpace(fileName))
throw new ArgumentException(nameof(fileName));
if (String.IsNullOrWhiteSpace(relativeDirectory))
relativeDirectory = String.Empty;
relativeDirectory = relativeDirectory.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
if (relativeDirectory.StartsWith(Path.DirectorySeparatorChar.ToString()))
relativeDirectory = relativeDirectory.Substring(1, relativeDirectory.Length - 1);
RelativeDirectory = relativeDirectory;
WorkspaceRootDir = String.IsNullOrWhiteSpace(workspaceRootDir)
? Directory.GetCurrentDirectory()
public byte[] FileData => fileData == null
? (fileData = File.ReadAllBytes(AbsolutePathToFile))
public string FileName { get; private set; }
public string RelativeDirectory { get; private set; }
public string AbsolutePathToFile => Path.Combine(WorkspaceRootDir, RelativeDirectory, FileName);
public string WorkspaceRootDir { get; private set; }
public interface ITaskContext
void PublishArtifact(IArtifact artifact);
string CurrentWorkspace { get; }
public interface IStageContext
string StageName { get; }
string StageDescription { get; }