Rory Primrose

Learn from my mistakes, you don't have time to make them yourself

View project on GitHub

Icon support for custom Windows Workflow activities

Creating a custom dependency resolution activity for WF gave me the opportunity to learn a lot about the latest version of Workflow Foundation. Adding support for custom icons is a simple requirement that often came up when creating new activities.

There are two places that provide this icon support. The first is in the Visual Studio toolbox and the second is on the activity design surface. I have been using images from the awesome famfamfam Silk collection for these activities.

Read More

Custom Windows Workflow activity for dependency resolution–Wrap up

I have been writing a series of posts recently about implementing a custom WF activity that will provide dependency resolution support for WF4 workflows. image

The InstanceResolver activity caters for lazy loading dependencies, multiple resolutions on the one activity, workflow persistence (including support for non-serializable dependencies) and lifetime management of the resolved dependencies. The activity uses Unity as the backend IoC container however this could be modified to support a different container with minimal changes.

Read More

Neovolve.Toolkit 1.0 RTW

I have finally marked my Neovolve.Toolkit project as stable for version 1.0. It includes the recent work I have done for WF4. The toolkit comes with the binaries, a chm help file for documentation information and xml comment files for intellisense in Visual Studio.

You can download the toolkit from the project on Codeplex.

The following tables outline the types available in the namespaces across the toolkit assemblies. The information here is copied from the compiled help file.

Read More

Custom Windows Workflow activity for dependency resolution–Part 6

The previous post in this series provided a custom updatable generic type argument implementation for the InstanceResolver activity. This post will look at the the XAML designer support for this activity.

The designer support for the InstanceResolver intends to display only the number of dependency resolutions that are configured according to the ArgumentCount property. Each dependency resolution shown needs to provide editing functionality for the resolution type, resolution name and the name of the handler reference.image

The XAML for the designer defines the activity icon, display for each argument and the child activity to execute. Each of the arguments is bound to an attached property that defines whether that argument is visible to the designer.

Read More

Custom Windows Workflow activity for dependency resolution–Part 5

The previous post covers the initial background for designer support of custom Windows Workflow activities. This post outlines a customised version of the updatable generic type support outlined in this post that is specific to the InstanceResolver activity.

One of my original design goals for this custom activity was to provide adequate designer support. The initial version of this custom activity resolved a single dependency. This was clearly limited as I often have multiple instance resolutions that I use in a workflow. A simple workaround would be to nest several of these activities to achieve the desired result however this would result in a very messy workflow design.

The implementation of the InstanceResolver activity avoids this scenario by supporting up to 16 dependency resolutions. This presents a usability issue with the designer support for the activity. The activity will provide 16 potential dependency resolutions even when just one or two are used. The activity designer addresses this by leveraging the ArgumentCount property of InstanceResolver that determines how many arguments are used by the activity. One area that this property value is used is in the behaviour of the updatable generic type support.

Read More

Custom Windows Workflow activity for dependency resolution–Part 4

The posts in this series have looked at providing a custom activity for dependency resolution in Windows Workflow. The series will now take a look at providing designer support for this activity. This post will cover the IRegisterMetadata interface and support for custom morphing.

Designer Support

The first action to take when creating WF4 activity designer support is to create a new Visual Studio project. The name of this project should be prefixed with the name of the assembly that contains the activities related to the designers. The project should have the suffix of “Design”. In the case of my Toolkit project, the assembly that contains the custom activities is called Neovolve.Toolkit.Workflow.dll and the designer assembly is called Neovolve.Toolkit.Workflow.Design.dll.

Read More

Creating updatable generic Windows Workflow activities

This post is a segue from the current series on building a custom activity for supporting dependency resolution in Windows Workflow (here, here, here and here so far). This post will outline how to support updating generic type arguments of generic activities in the designer. This technique is used in the designer support for the InstanceResolver activity that has been discussed throughout the series.

The implementation of this is modelled from the support for this functionality in the generic WF4 activities such as ForEach<T> and ParallelForEach<T>. Unfortunately the logic that drives this is marked as internal and is therefore not available to developers who create custom generic activities.

In the case of the ForEach<T> activity, the default generic type value used is int. image

Read More

Custom Windows Workflow activity for dependency resolution–Part 3

My previous post provided the base framework for resolving dependencies, handling persistence and tearing down resolved dependencies in Windows Workflow. This post will provide the custom activity for exposing resolved dependencies to a workflow.

The original implementation of this activity supported resolving a single dependency. It has slowly evolved into one that can support up to 16 dependencies. The reason for this specific number is that the activity leverages the ScheduleAction method on the NativeActivityContext class. This method has overloads that support up to 16 generic arguments. This avoids the developer needing to use nested activities to achieve the same result if only one dependency was supported.

The ScheduleAction method provides the ability for a child activity to be scheduled for execution with one or more delegate arguments. This is the way that ForEach<T> and ParallelForEach<T> activities work. In these cases the argument defines the item being provided in the iterator of the loop behind the activity. This is seen below being defined as the variable “item”.image

Read More

Custom Windows Workflow activity for dependency resolution–Part 2

My previous post described the design goals for creating a custom WF4 activity that provides dependency resolution functionality. This post will look at the underlying support for making this happen.

The main issue with dependency resolution/injection in WF is supporting persistence. An exception will be thrown when a workflow is persisted when it holds onto a dependency that is not serializable. The previous post indicated that the solution to this issue is to have the workflow persist the resolution description and explicitly prevent serialization of the resolved instance itself.

The way this is done is via an InstanceHandler<T> class.

Read More

Custom Windows Workflow activity for dependency resolution–Part 1

The previous post talked about the issues with supporting DI in WF4. The nature of Windows Workflow means that there is no true support for DI. Using a custom extension and activity will allow for pulling in dependencies to a workflow while catering for the concerns outlined in the previous post. This series will refer to the dependency injection concept as dependency resolution because this technique is more aligned with the Service Locator pattern than DI.

This first part will go through the design goals of the custom activity.

The custom activity will have the following characteristics:

Read More