Rory Primrose

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

View project on GitHub

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

Dependency injection options for Windows Workflow 4

I’m a fan of DI for all the benefits that it brings. Unfortunately dependency injection is not really supported with Windows Workflow.

DI is a pattern in which dependencies are calculated outside an entity and provided to the entity for it to use. The DI container is responsible for creating and managing these dependencies and injecting them onto the entity.

WF does not fully support this model. Any dependencies calculated outside a workflow must be provided to the workflow execution engine as a dictionary of input parameters. A DI container can be used resolve the dependencies, however providing them to the workflow via the workflow engine is a manual process. This means that constructor, property and method injection are not supported as you cannot use a container to resolve or build up a workflow instance.

Read More

TFS Build fails for no indicated reason with code contracts in test assemblies

This has been a curly one for a few months and I’ve finally had some time to resolve the issue. My team has been running TFS Build 2010 with gated check-ins where the build does MSI deploys then runs unit and integration tests.

All of a sudden the builds started failing with no indication as to why. The build activity log just stops and does not contain errors. The MS build log file also does not contain any errors. The event log on the build server does shed some light on the situation however.

Read More

Getting meaningful exceptions from WF

Overall I love the changes made to WF4. The latest workflow support is a huge leap forward from the 3.x versions. Unfortunately both versions suffer the same issues regarding feedback for the developer when exceptions are thrown.

Consider the following simple workflow example.

Read More

Developing multi-threaded workflows

Most people (myself included) assume that the Parallel and ParallelForEach<t> activities in WF4 run each child in parallel on multiple threads. Unfortunately this is not the case. Each child activity is scheduled in the workflow runtime at the same time. The child activities will only start running in “parallel” if one of the branches is in a waiting state. You can read this post which links to this post for some more detailed information

You can achieve multi-threaded parallel execution by using AsyncCodeActivity derived activities (such as InvokeMethod) with the RunAsynchronously set to True running in a Parallel or ParallelForEach<t> activity. Consider the following workflow.

Read More

Cleaning a VS2010 solution with a sledgehammer

My workplace has been having issues with VS2010 picking up old assemblies since we have been using VS2010 on a complex services solution. The issue usually pops up when executing test runs with the built in support for MSTest. This occasionally happened in VS2008 but is much more prevalent in 2010. The scenario seems to be that somewhere between the IDE and MSTest is picking up assemblies from prior TestResults directories if the assembly can’t be found in bin\Debug or bin\Release directories. This means that the normal clean operation under the build menu is not sufficient to get rid of this problem.

Enter the sledgehammer. I wrote a little utility that will recursively go through each bin, obj and TestResults folder under the solution path and delete everything it can (including read-only files). Any exceptions encountered will be output to the console. The code itself is really simple.

Read More

Caching workflow activities to increase performance

David Paquette posted last year about the performance characteristics of WF4. Runtime performance is a typical complaint with WF but it can be minimised as David has indicated. Adding some caching logic for workflow activity instances will avoid the expensive start-up process for invoking activities. Subsequent activity invocations will be much faster by getting the activity instance from the cache rather than creating a new one.

I’ve put together an ActivityStore class that handles this caching requirement.

Read More