workflow-core
workflow-core copied to clipboard
Passing context.item from one step as output to next step as intut?
Hi,
is there a way to pass in a foreach loop a data object from one step to the next?
For Example in sample below I would like to passe from first step "Compress" the step.outFile to the next step "Image" as context.Item. As .Output does not have a context my idea does not work. Is there another way to do this?
.ForEach(data => data.ProcessingFiles)
.Do(x =>
x.StartWith<CompressAction>()
.Name("myCompressInLoop")
.Input((step, data, context) =>
{
step.inFile = context.Item;
})
.Output((step, data) =>
{
context.Item = step.outFile;
})
.Then<ImageAction>()
.Name("myImageInLoop")
.Input((step, data, context) =>
{
step.inFile = context.Item;
})
.Output((step, data) =>
{
data.AddProcessingFile = step.outFile;
})
)
Why don't you just map the compress output to a value on the workflow data object and then map to input of the next step to that field?
I can keep a list of the current loop steps in the wf data object, will give this a try.
In the scenario where the workflow engine is running on multiple instances how is wf data object synchronized between them? Is a change in the wf data object transactional?
I do not think that is transactional.
Here is a workflow with ForEach,
builder
.ForEach(data => new List<int> { 1, 2, 3, 4 })
.Do(x => x
.StartWith<DoForeach>()
.Input(step => step.Item, (Data data, IStepExecutionContext context) => (int)context.Item)
.Output(w => w.Id, step => step.ItemOut)
.Then<DoForeach>()
.Input(s => s.Item, (step, context) => step.Id)
)
.OnError(WorkflowErrorHandling.Terminate);
and the Data
class is defined as
public class Data
{
public int Id { get; set; }
}
The DoForeach
will take Item
as input, and doubles it as output ItemOut
. The execution result shows
Starting workflow...
78e3e226-8e0f-456c-86fd-eea655532e62
1
2
3
4
8
8
8
8
So there I think these parallel steps takes a shared instance of Data
. I think the only way is to use a Dictionary
and map each loop to a cell in the dictionary, like this
public class Data
{
public IDictionary<int, int> Id { get; set; } = new Dictionary<int, int>();
}
builder
.ForEach(data => new List<int> { 1, 2, 3, 4 })
.Do(x => x
.StartWith<DoForeach>()
.Input(step => step.Item, (Data data, IStepExecutionContext context) => (int)context.Item)
.Output((s, w) => w.Id[s.Item] = s.ItemOut)
.Then<DoForeach>()
.Input(s => s.Item, (step, context) => step.Id[(int)context.Item])
)
.OnError(WorkflowErrorHandling.Terminate);
I wonder if there is better way of handling this pattern.