Monday Apr 13, 2009

Providing dependencies to Workflow instances hosted with WorkflowServiceHost

In my usage, I have components I want to inject, often instantiated/serviced via Spring.NET .  This feels a little strange relative to most Spring.NET usage, as I will place our dependencies in the workflow runtime as Services, and then use an override of OnActivityExecutionContextLoad to have the workflow 'pull' the dependencies back in from the workflow runtime. This seems odd, but it gets the components where they need to be without building an IOC container dependency in the workflow or building an extension for your IOC gadget.  The workflow runtime is a container of its own, and the workflows are serviced components.  This approach adapts a generic object creation strategy to the WF/WCF model - the WF/WCF way.

In the workflow, note [NonSerialized] private value for the service we're providing to the workflow.  You don't want your singleton services serialized along with workflow instances, do you?:

public sealed partial class Workflow1 : StateMachineWorkflowActivity
{
public Workflow1()
{
InitializeComponent();
}

[NonSerialized]
private IStuffDoer stuffDoer;

...
protected override void OnActivityExecutionContextLoad(IServiceProvider provider)
{
base.OnActivityExecutionContextLoad(provider);

stuffDoer = provider.GetService(typeof(IStuffDoer)) as IStuffDoer;
}
...

And we add the dependency to the workflow runtime in the host process like so (using 'new ...' for simplicity, you could pull from an IOC container here just as easily):

Console.WriteLine("Starting host.");
WorkflowServiceHost host = new WorkflowServiceHost(typeof(Workflow1));

host.Description.Behaviors.Find().WorkflowRuntime.AddService(
new StuffDoerImpl());

host.Open();
Console.WriteLine("Host started." + Environment.NewLine);
Console.WriteLine("Press Enter to stop:");
Console.ReadLine();
host.Close();

From there, the service is available for use in your workflow code activities. You can promote it to a public property if you want to bind it to activity properties.

It took a lot of Google-time to figure out how to get the dependency into the service host via the host description behaviors, and yet more to figure out how to get it from the ActivityExecutionContext into the workflow. I hope this saves someone some time!

Comments:

Post a Comment:
  • HTML Syntax: Allowed