This code contains a sequential workflow running in a console application.
There is a sequence and inside the sequence a QueryActions and ForeachLoop.
The QueryActions Activity is a custom activity that you can create through Visual Studio add >> new >> .... etc... it gives you a design surface where you can drop standard out of the box activities. In this case the QueryActions activity has inside of it a standard toolbox DBQuery activity which lets you point and click your way to a database select. The QueryActions activity also takes some parameters it can supply to its DBQuery Acitivity.... Actions and DBConnectionContext. The QueryActions activity outputs a List<Action>. which is a generic list of Actions. Actions is a Class manually created with XAML.
Inside the QueryActions activity the DBQuery fills the List<Action>. The List<Action> is then returned to the top level sequence activity and then the FOREACH activity is running iterating of the List<Action>.
Inside the BODY of the FOREACH you can see other Activities being executed. Namely CopyFile and DeleteAction activities. The CopyFile Activity is another custom activity around a powershell commandlet activity that comes out of the box with WF4.0 The DeleteAction activity is a custom activity around DBQuery again. This time executing a delete of records.
The whole workflow does is take a list of file locations from the database, copies files from one location to another then deletes the records in the database.
C#
namespace CustomActivities
{
using System;
using System.Linq;
using System.Threading;
using System.WorkflowModel;
using System.WorkflowModel.Activities;
using System.Collections.Generic;
class Program
{
static void Main(string[] args)
{
AutoResetEvent syncEvent = new AutoResetEvent(false);
Variable<DbConnectionContext> context = new Variable<DbConnectionContext> { Default = new DbConnectionContext("System.Data.SqlClient", "Data Source=localhost;Integrated Security=SSPI;Initial Catalog=HOL_Lab2") };
Variable<IList<Action>> actions = new Variable<IList<Action>> { Default = new List<Action>() };
Variable<Action> action = new Variable<Action>();
var sequence = new Sequence
{
Variables = { context, actions },
Activities =
{
new QueryActions { Actions = actions, ConnectionContext = context },
new ForEach<Action>
{
Values = actions,
Body = new ActivityAction<Action>
{
Argument = action,
Handler = new Sequence
{
Activities =
{
new CopyFile { Source = new InArgument <string>(e=>action.Get(e).SourceFile), Destination = new InArgument <string>(e=>action.Get(e).DestinationFile) },
new DeleteAction { ConnectionContext = context, ActionId = new InArgument<int>(e=>action.Get(e).ActionId) }
}
}
}
}
}
};
WorkflowInstance myInstance = WorkflowInstance.Create(sequence);
myInstance.Completed += delegate(object sender, WorkflowCompletedEventArgs e) { syncEvent.Set(); };
myInstance.Aborted += delegate(object sender, WorkflowAbortedEventArgs e) { Console.WriteLine(e.Reason); syncEvent.Set(); };
myInstance.Resume();
syncEvent.WaitOne();
}
}
}
Note: The program above creates a workflow containing a sequence. The sequence will execute firs the QueryActions activity that returns a list of actions. Foreach action the workflow will execute the CopyFile and DeleteAction activities.