Aug 18 2010

Getting meaningful exceptions from WF

Category: .NetRory Primrose @ 08:33

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.

image

namespace WorkflowConsoleApplication1
{
    using System;
    using System.Activities;

    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                WorkflowInvoker.Invoke(new Workflow1());
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }

            Console.ReadKey();
        }
    }
}

This example provides the following output.

System.InvalidOperationException: Something went wrong
   at System.Activities.WorkflowApplication.Invoke(Activity activity, IDictionar
y`2 inputs, WorkflowInstanceExtensionManager extensions, TimeSpan timeout)
   at System.Activities.WorkflowInvoker.Invoke(Activity workflow, TimeSpan timeo
ut, WorkflowInstanceExtensionManager extensions)
   at System.Activities.WorkflowInvoker.Invoke(Activity workflow)
   at WorkflowConsoleApplication1.Program.Main(String[] args) in e:\users\profil
edr\documents\visual studio 2010\Projects\WorkflowConsoleApplication2\WorkflowCo
nsoleApplication2\Program.cs:line 12

Exceptions thrown from the workflow engine identify the exception type and message but do not contain an accurate stack trace. Exceptions are caught by the workflow engine and re-thrown when WorkflowInvoker.Invoke is used. This means that the stack trace identifies where the exception has been re-thrown rather than where the exception was originally raised.

Debugging WF activities with this constraint is very difficult. Trying to debug your workflows gets exponentially harder with increasing complexity of the workflow system and it's underlying components. This is compounded when the exception (such as a NullReferenceException) doesn't provide enough information by itself to pinpoint where the exception was thrown.

The solution to this is in two parts. The first improvement is to provide more detail in the stack trace and the second is to identify the activity hierarchy involved.

Enhancing the stack trace

Using the throw statement on an existing exception instance wipes out any existing stack trace information. This is why you should never catch ex then throw ex, you should always just use the throw statement by itself. This isn’t possible in the case of the workflow engine as it has caught the exception on a different thread and has no choice but to throw the exception instance back on the original calling thread.

The trick here is to get the exception to preserve the original stack trace when it is re-thrown. Exception has a method called InternalPreserveStackTrace that will do this for us. Reflection must be used here because the method is marked as internal.

The first thing to change is that we need to use WorkflowApplication directly rather than WorkflowInvoker. WorkflowInvoker is great for simplicity but does not provide direct access to the thrown exception before it is re-thrown. Using WorkflowApplication provides the ability to hook the OnUnhandledException action where the exception is available. The reflected InternalPreserveStackTrace method can then be invoked on the exception instance before it is re-thrown.

namespace WorkflowConsoleApplication1
{
    using System;
    using System.Activities;
    using System.Collections.Generic;
    using System.Reflection;
    using System.Text;
    using System.Threading;

    internal class ActivityInvoker
    {
        private static readonly MethodInfo _preserveStackTraceMethod = GetExceptionPreserveMethod();

        public static IDictionary<String, Object> Invoke(Activity activity, IDictionary<String, Object> inputParameters = null)
        {
            if (inputParameters == null)
            {
                inputParameters = new Dictionary<String, Object>();
            }

            WorkflowApplication application = new WorkflowApplication(activity, inputParameters);
            Exception thrownException = null;
            IDictionary<String, Object> outputParameters = new Dictionary<String, Object>();
            ManualResetEvent waitHandle = new ManualResetEvent(false);

            application.OnUnhandledException = (WorkflowApplicationUnhandledExceptionEventArgs arg) =>
            {
                // Preserve the stack trace in this exception
                // This is a hack into the Exception.InternalPreserveStackTrace method that allows us to re-throw and preserve the call stack
                _preserveStackTraceMethod.Invoke(arg.UnhandledException, null);

                thrownException = arg.UnhandledException;

                return UnhandledExceptionAction.Terminate;
            };
            application.Completed = (WorkflowApplicationCompletedEventArgs obj) =>
            {
                waitHandle.Set();

                outputParameters = obj.Outputs;
            };
            application.Aborted = (WorkflowApplicationAbortedEventArgs obj) => waitHandle.Set();
            application.Idle = (WorkflowApplicationIdleEventArgs obj) => waitHandle.Set();
            application.PersistableIdle = (WorkflowApplicationIdleEventArgs arg) =>
            {
                waitHandle.Set();

                return PersistableIdleAction.Persist;
            };
            application.Unloaded = (WorkflowApplicationEventArgs obj) => waitHandle.Set();

            application.Run();

            waitHandle.WaitOne();

            if (thrownException != null)
            {
                throw thrownException;
            }

            return outputParameters;
        }

        private static MethodInfo GetExceptionPreserveMethod()
        {
            return typeof(Exception).GetMethod("InternalPreserveStackTrace", BindingFlags.Instance | BindingFlags.NonPublic);
        }
    }
}

Changing the example program code to use this ActivityInvoker class rather than WorkflowInvoker now provides some more detailed stack trace information.

System.InvalidOperationException: Something went wrong
   at System.Activities.Statements.Throw.Execute(CodeActivityContext context)
   at System.Activities.CodeActivity.InternalExecute(ActivityInstance instance,
ActivityExecutor executor, BookmarkManager bookmarkManager)
   at System.Activities.ActivityInstance.Execute(ActivityExecutor executor, Book
markManager bookmarkManager)
   at System.Activities.Runtime.ActivityExecutor.ExecuteActivityWorkItem.Execute
Body(ActivityExecutor executor, BookmarkManager bookmarkManager, Location result
Location)
   at WorkflowConsoleApplication1.ActivityInvoker.Invoke(Activity activity, IDic
tionary`2 inputParameters) in e:\users\profiledr\documents\visual studio 2010\Pr
ojects\WorkflowConsoleApplication2\WorkflowConsoleApplication2\ActivityInvoker.c
s:line 82
   at WorkflowConsoleApplication1.Program.Main(String[] args) in e:\users\profil
edr\documents\visual studio 2010\Projects\WorkflowConsoleApplication2\WorkflowCo
nsoleApplication2\Program.cs:line 11

The stack trace with preservation now includes the stack frames between ActivityInvoker.Invoke and the class that originally threw the exception. This is particularly helpful when the exception was thrown in an underlying component. Unfortunately the architecture of WF does not often provide much of a stack trace in itself. Preserving the stack trace in this simple scenario has added helpful information but not enough to make it really easy to debug.

Identifying the activity hierarchy

Identifying the hierarchy of activities being executed will add further debugging assistance. The Activity class in the 3.x version of WF contained a public Parent property. You could recursively traverse up the chain of parent activities to create a hierarchy of activities to provide this information. This property is still there in version 4.0 but is now internal. Using reflection is again the only option for obtaining this information.

A tweak to the exception logic in the ActivityInvoker class will hook into the Activity.Parent property to calculate the activity hierarchy.

namespace WorkflowConsoleApplication1
{
    using System;
    using System.Activities;
    using System.Collections.Generic;
    using System.Reflection;
    using System.Text;
    using System.Threading;

    internal class ActivityInvoker
    {
        private static readonly PropertyInfo _parentProperty = GetActivityParentProperty();

        private static readonly MethodInfo _preserveStackTraceMethod = GetExceptionPreserveMethod();

        public static Exception CreateActivityFailureException(Exception exception, Activity source)
        {
            // Create the hierarchy of activity names
            Activity activity = source;
            StringBuilder builder = new StringBuilder(exception.Message);
            builder.AppendLine();
            builder.AppendLine();

            builder.AppendLine("Workflow exception throw from the following activity stack:");

            while (activity != null)
            {
                builder.AppendLine(activity + " - " + activity.GetType().FullName);

                activity = _parentProperty.GetValue(activity, null) as Activity;
            }

            return new ActivityFailureException(builder.ToString(), exception);
        }

        public static IDictionary<String, Object> Invoke(Activity activity, IDictionary<String, Object> inputParameters = null)
        {
            if (inputParameters == null)
            {
                inputParameters = new Dictionary<String, Object>();
            }

            WorkflowApplication application = new WorkflowApplication(activity, inputParameters);
            Exception thrownException = null;
            IDictionary<String, Object> outputParameters = new Dictionary<String, Object>();
            ManualResetEvent waitHandle = new ManualResetEvent(false);

            application.OnUnhandledException = (WorkflowApplicationUnhandledExceptionEventArgs arg) =>
            {
                // Preserve the stack trace in this exception
                // This is a hack into the Exception.InternalPreserveStackTrace method that allows us to re-throw and preserve the call stack
                _preserveStackTraceMethod.Invoke(arg.UnhandledException, null);

                thrownException = CreateActivityFailureException(arg.UnhandledException, arg.ExceptionSource);

                return UnhandledExceptionAction.Terminate;
            };
            application.Completed = (WorkflowApplicationCompletedEventArgs obj) =>
            {
                waitHandle.Set();

                outputParameters = obj.Outputs;
            };
            application.Aborted = (WorkflowApplicationAbortedEventArgs obj) => waitHandle.Set();
            application.Idle = (WorkflowApplicationIdleEventArgs obj) => waitHandle.Set();
            application.PersistableIdle = (WorkflowApplicationIdleEventArgs arg) =>
            {
                waitHandle.Set();

                return PersistableIdleAction.Persist;
            };
            application.Unloaded = (WorkflowApplicationEventArgs obj) => waitHandle.Set();

            application.Run();

            waitHandle.WaitOne();

            if (thrownException != null)
            {
                throw thrownException;
            }

            return outputParameters;
        }

        private static PropertyInfo GetActivityParentProperty()
        {
            return typeof(Activity).GetProperty("Parent", BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.NonPublic);
        }

        private static MethodInfo GetExceptionPreserveMethod()
        {
            return typeof(Exception).GetMethod("InternalPreserveStackTrace", BindingFlags.Instance | BindingFlags.NonPublic);
        }
    }
}

The change here calculates the activity hierarchy and appends it to the exception message. A custom ActivityFailureException is used to help identify that this an exception handled from the workflow engine. The original exception is still available via the InnerException property.

The output of the program now provides the extended stack trace and the activity hierarchy.

WorkflowConsoleApplication1.ActivityFailureException: Something went wrong

Workflow exception thrown from the following activity stack:
1.5: Throw - System.Activities.Statements.Throw
1.4: Fourth Sequence - System.Activities.Statements.Sequence
1.3: Third Sequence - System.Activities.Statements.Sequence
1.2: Second Sequence - System.Activities.Statements.Sequence
1.1: First Sequence - System.Activities.Statements.Sequence
1: Workflow1 - WorkflowConsoleApplication1.Workflow1
 ---> System.InvalidOperationException: Something went wrong
   at System.Activities.Statements.Throw.Execute(CodeActivityContext context)
   at System.Activities.CodeActivity.InternalExecute(ActivityInstance instance,
ActivityExecutor executor, BookmarkManager bookmarkManager)
   at System.Activities.ActivityInstance.Execute(ActivityExecutor executor, Book
markManager bookmarkManager)
   at System.Activities.Runtime.ActivityExecutor.ExecuteActivityWorkItem.Execute
Body(ActivityExecutor executor, BookmarkManager bookmarkManager, Location result
Location)

   --- End of inner exception stack trace ---
   at WorkflowConsoleApplication1.ActivityInvoker.Invoke(Activity activity, IDic
tionary`2 inputParameters) in e:\users\profiledr\documents\visual studio 2010\Pr
ojects\WorkflowConsoleApplication2\WorkflowConsoleApplication2\ActivityInvoker.c
s:line 80
   at WorkflowConsoleApplication1.Program.Main(String[] args) in e:\users\profil
edr\documents\visual studio 2010\Projects\WorkflowConsoleApplication2\WorkflowCo
nsoleApplication2\Program.cs:line 11

The combination of these two pieces of information will now allow you to quickly identify where the exception is being thrown in or through your workflow assembly.

Tags: ,

Aug 6 2010

Developing multi-threaded workflows

Category: .NetRory Primrose @ 07:21

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.

image

Each parallel branch writes the start time to the console, runs a Thread.Sleep for 2, 4 or 6 seconds and writes the end time. The following is written to the console if each InvokeMethod activity has RunAsynchronously set to False.

Starting - 6/08/2010 10:41:38 AM
Starting First - 6/08/2010 10:41:38 AM
Finishing First - 6/08/2010 10:41:40 AM
Starting Second - 6/08/2010 10:41:41 AM
Finishing Second - 6/08/2010 10:41:45 AM
Starting Third - 6/08/2010 10:41:45 AM
Finishing Third - 6/08/2010 10:41:51 AM
Completed - 6/08/2010 10:41:51 AM

Each branch in the parallel is waiting until the previous branch has completed. The following is written to the console if each InvokeMethod activity has RunAsynchronously set to True.

Starting - 6/08/2010 10:47:35 AM
Starting First - 6/08/2010 10:47:35 AM
Starting Second - 6/08/2010 10:47:35 AM
Starting Third - 6/08/2010 10:47:35 AM
Finishing First - 6/08/2010 10:47:37 AM
Finishing Second - 6/08/2010 10:47:39 AM
Finishing Third - 6/08/2010 10:47:41 AM
Completed - 6/08/2010 10:47:41 AM

Each parallel branch has now executed on different threads. The overall affect is that the workflow now runs must faster.

ParallelForEach<T> works in the same manner. This workflow can be refactored to the following:

image

The result without asynchronous processing is:

Starting - 6/08/2010 11:55:09 AM
Starting 1 - 6/08/2010 11:55:09 AM
Finishing 1 - 6/08/2010 11:55:11 AM
Starting 2 - 6/08/2010 11:55:11 AM
Finishing 2 - 6/08/2010 11:55:16 AM
Starting 3 - 6/08/2010 11:55:16 AM
Finishing 3 - 6/08/2010 11:55:22 AM
Completed - 6/08/2010 11:55:22 AM

The result with asynchronous processing is:

Starting - 6/08/2010 11:56:02 AM
Starting 1 - 6/08/2010 11:56:02 AM
Starting 2 - 6/08/2010 11:56:02 AM
Starting 3 - 6/08/2010 11:56:02 AM
Finishing 1 - 6/08/2010 11:56:04 AM
Finishing 2 - 6/08/2010 11:56:07 AM
Finishing 3 - 6/08/2010 11:56:08 AM
Completed - 6/08/2010 11:56:08 AM

What happens when an exception is thrown? If the exception is thrown in the parallel branch, it will stop executing all the other running branches and the exception will be thrown up the call stack. Any exceptions thrown from within the asynchronous code will have the exception pushed back onto the original workflow execution thread and then thrown. Effectively there is no difference regarding where the exception is thrown from, the parallel branches will be stopped.

Tags: ,

Aug 2 2010

Cleaning a VS2010 solution with a sledgehammer

Category: .Net | My SoftwareRory Primrose @ 07:11

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.

namespace Neovolve.SolutionCleaner
{
    using System;
    using System.IO;

    internal class Program
    {
        private static void DeleteDirectory(String directoryPath)
        {
            String[] directories = Directory.GetDirectories(directoryPath);

            for (int index = 0; index < directories.Length; index++)
            {
                String childDirectory = directories[index];

                DeleteDirectory(childDirectory);
            }

            Console.WriteLine("Cleaning directory " + directoryPath);

            String[] files = Directory.GetFiles(directoryPath);

            for (Int32 index = 0; index < files.Length; index++)
            {
                String file = files[index];

                Console.WriteLine("Deleting file " + file);

                try
                {
                    FileInfo fileInfo = new FileInfo(file);

                    if (fileInfo.IsReadOnly)
                    {
                        fileInfo.IsReadOnly = false;
                    }

                    fileInfo.Delete();
                }
                catch (IOException ex)
                {
                    Console.WriteLine(ex);
                }
                catch (UnauthorizedAccessException ex)
                {
                    Console.WriteLine(ex);
                }
            }

            Console.WriteLine("Deleting directory " + directoryPath);

            try
            {
                Directory.Delete(directoryPath, true);
            }
            catch (IOException ex)
            {
                Console.WriteLine(ex);
            }
            catch (UnauthorizedAccessException ex)
            {
                Console.WriteLine(ex);
            }
        }

        private static void Main(String[] args)
        {
            foreach (String argument in args)
            {
                if (Directory.Exists(argument))
                {
                    ProcessDirectory(argument);
                }
            }

            Console.WriteLine("Completed");
        }

        private static void ProcessChildDirectory(String directoryPath, String childDirectory)
        {
            String[] directories = Directory.GetDirectories(directoryPath, childDirectory, SearchOption.AllDirectories);

            foreach (String directory in directories)
            {
                DeleteDirectory(directory);
            }
        }

        private static void ProcessDirectory(String directoryPath)
        {
            ProcessChildDirectory(directoryPath, "bin");
            ProcessChildDirectory(directoryPath, "obj");
            ProcessChildDirectory(directoryPath, "TestResults");
        }
    }
}

The best way to hook this up is via the Visual Studio External Tools dialog by passing in the current solutions directory path.

image

This method also allows you to output the console results to the Output window for a more integrated experience.

NOTE: It’s a good idea to run a Visual Studio clean from the build menu before running this tool to get Visual Studio to release any locks it has on files in these directories. We haven’t had any assembly version conflicts since running this tool.

You can either compile the above yourself or grab the executable below.

Neovolve.SolutionCleaner.zip (2.61 kb)

Tags:

Jul 27 2010

Tracking lazy loaded build trees in Unity

Category: .NetRory Primrose @ 08:31

I recently posted a Unity extension for disposing build trees created by Resolve and BuildUp actions. Unity has a feature that supports lazy loading injected dependencies that the original disposal extension didn’t cater for.

Consider the following example.

using System;
using Microsoft.Practices.Unity;
using Neovolve.Toolkit.Unity;

namespace Neovolve.LazyInjectionTesting
{
    class Program
    {
        static void Main(String[] args)
        {
            IUnityContainer container = new UnityContainer();

            container.AddExtension(new DisposableStrategyExtension());
            container.RegisterType(typeof(ITester), typeof(Tester));

            Root root = container.Resolve<Root>();

            container.Teardown(root);

            Console.WriteLine(root.TestInstance.IsDisposed);
            Console.ReadKey();
        }
    }

    public class Root
    {
        public Root(ITester tester)
        {
            TestInstance = tester;
        }

        public ITester TestInstance
        {
            get;
            private set;
        }
    }

    public interface ITester
    {
        void DoSomething();

        Boolean IsDisposed
        {
            get;
        }
    }

    public class Tester : ITester, IDisposable
    {
        public void DoSomething()
        {
        }

        public void Dispose()
        {
            IsDisposed = true;
        }

        public bool IsDisposed
        {
            get;
            private set;
        }
    }
}

This example resolves an instance of Root that has a dependency of type ITester. The build tree tracked by the disposal extension for this example is:

  • Root
    • Tester

Tester exposes a property that indicates whether the instance has been disposed. The disposal extension will ensure that all items in the build tree are disposed when the container is told to tear down the root instance. The Tester.IsDisposed property returns True when this console code is run.

Lazy loading dependencies is achieved by changing the injection type from T to Func<T>. This can be done in the above example by changing the Root constructor from public Root(ITester tester) to public Root(Func<ITester> tester). The example above now looks like the following. This delegate then needs to be invoked to get Unity to resolve the dependency instance.

using System;
using Microsoft.Practices.Unity;
using Neovolve.Toolkit.Unity;

namespace Neovolve.LazyInjectionTesting
{
    class Program
    {
        static void Main(String[] args)
        {
            IUnityContainer container = new UnityContainer();

            container.AddExtension(new DisposableStrategyExtension());
            container.RegisterType(typeof(ITester), typeof(Tester));

            Root root = container.Resolve<Root>();
            ITester testInstance = root.TestInstance();

            container.Teardown(root);

            Console.WriteLine(testInstance.IsDisposed);
            Console.ReadKey();
        }
    }

    public class Root
    {
        public Root(Func<ITester> tester)
        {
            TestInstance = tester;
        }

        public Func<ITester> TestInstance
        {
            get;
            private set;
        }
    }

    public interface ITester
    {
        void DoSomething();

        Boolean IsDisposed
        {
            get;
        }
    }

    public class Tester : ITester, IDisposable
    {
        public void DoSomething()
        {
        }

        public void Dispose()
        {
            IsDisposed = true;
        }

        public bool IsDisposed
        {
            get;
            private set;
        }
    }
}

Unity will create a delegate for Func<ITester> in order to call the constructor on Root. The delegate is a function that will resolve ITester from the container when the delegate is invoked. This means that the resolution of Root occurs at a different time to the resolution of ITester. The DisposableStrategyExtension is now tracking two build trees rather than one. The build tree that contains Root does not contain ITester and therefore the disposal strategy can’t dispose the dependency when container.TearDown(root) is invoked. The console application now returns False because the DisposalStrategyExtension does not understand that the two build trees are related.

I have updated the DisposableStrategyExtension to correctly track build trees of these lazy loaded dependencies.

The PostBuildUp method is the second half of the logic that creates a build tree for each Unity build operation in this extension. The update to track lazy loaded build trees is to detect that the dependency created (context.Existing) is a delegate. If this is the case then  a wrapper delegate is created and returned instead.

public override void PostBuildUp(IBuilderContext context)
{
    if (context != null)
    {
        // Check if the item created is Func<T> for lazy loaded dependency injection
        if (context.Existing is Delegate)
        {
            context.Existing = CreateTrackedDeferredResolution((Delegate)context.Existing);
        }

        AssignInstanceToCurrentTreeNode(context.BuildKey, context.Existing);

        BuildTreeItemNode parentNode = CurrentBuildNode.Parent;

        if (parentNode == null)
        {
            // This is the end of the creation of the root node
            using (new LockWriter(_lock))
            {
                BuildTrees.Add(CurrentBuildNode);
            }
        }

        // Move the current node back up to the parent
        // If this is the top level node, this will set the current node back to null
        CurrentBuildNode = parentNode;
    }

    base.PostBuildUp(context);
}

The wrapper delegate will now be injected as the dependency rather than the Unity delegate. The wrapper delegate is created using the CreateTrackedDeferredResolution method. This method has some defensive coding to ensure that we are actually dealing with a Func<T> delegate. The wrapper delegate it creates is a function call out to a Resolve method on a custom DeferredResolutionTracker<T> class.

public Delegate CreateTrackedDeferredResolution(Delegate originalDeferredFunction)
{
    Type delegateType = originalDeferredFunction.GetType();

    if (delegateType.IsGenericType == false)
    {
        return originalDeferredFunction;
    }

    Type genericDelegateType = delegateType.GetGenericTypeDefinition();

    if (genericDelegateType.Equals(typeof(Func<>)) == false)
    {
        return originalDeferredFunction;
    }

    // This looks like a lazy loaded delegate for dependency injection
    // We need to redirect this through another method to manage the original build tree 
    // when the delegate invocation creates more instances
    Type[] genericArguments = delegateType.GetGenericArguments();

    if (genericArguments.Length > 1)
    {
        return originalDeferredFunction;
    }

    Type genericArgument = genericArguments[0];
    Type deferredTrackerType = typeof(DeferredResolutionTracker<>);
    Type[] typeArguments = new[]
                                {
                                    genericArgument
                                };
    Type genericDeferredTrackerType = deferredTrackerType.MakeGenericType(typeArguments);
    MethodInfo resolveMethod = genericDeferredTrackerType.GetMethod("Resolve");
    Object[] trackerArguments = new Object[]
                                    {
                                        originalDeferredFunction, this, CurrentBuildNode
                                    };
    Object resolvedTracker = Activator.CreateInstance(genericDeferredTrackerType, trackerArguments);

    return Delegate.CreateDelegate(delegateType, resolvedTracker, resolveMethod);
}

The DeferredResolutionTracker class takes in the original delegate, the parent node in the original build tree (the instance that the delegate is injected into) and a reference to the collection of build trees. Its Resolve method then invokes the original delegate to lazy load the dependency instance from Unity. It then searches the collection of build trees to find the build tree of that resolution action. That build tree is then removed from the collection and added as a child of the original parent node from the original build tree.

using System;
using System.Diagnostics.Contracts;
using System.Linq;

namespace Neovolve.Toolkit.Unity
{
    internal class DeferredResolutionTracker<T>
    {
        public DeferredResolutionTracker(
            Func<T> resolutionFunction, IBuildTreeTracker originalTracker, BuildTreeItemNode parentNode)
        {
            Contract.Requires<ArgumentNullException>(resolutionFunction != null, "No resolution function provided.");
            Contract.Requires<ArgumentNullException>(originalTracker != null, "No original tracker provided.");
            Contract.Requires<ArgumentNullException>(parentNode != null, "No parent node provided.");

            ResolutionFunction = resolutionFunction;
            OriginalTracker = originalTracker;
            ParentNode = parentNode;
        }

        public T Resolve()
        {
            T resolvedInstance = ResolutionFunction();

            BuildTreeItemNode deferredBuildTree =
                    OriginalTracker.BuildTrees.Where(x => IsDeferredBuildTreeReference(x, resolvedInstance)).
                        FirstOrDefault();

            if (deferredBuildTree == null)
            {
                return resolvedInstance;
            }

            // We have found the deferred build tree for the instance created by the deferred resolution function
            OriginalTracker.RemoveBuildTree(deferredBuildTree);

            // Add the build tree as a child to the parent node
            ParentNode.Children.Add(deferredBuildTree);

            return resolvedInstance;
        }

        private static Boolean IsDeferredBuildTreeReference(BuildTreeItemNode buildTreeNode, T resolvedInstance)
        {
            if (buildTreeNode == null)
            {
                return false;
            }

            if (buildTreeNode.ItemReference.IsAlive == false)
            {
                return false;
            }

            if (ReferenceEquals(buildTreeNode.ItemReference.Target, resolvedInstance))
            {
                return true;
            }

            return false;
        }

        private IBuildTreeTracker OriginalTracker
        {
            get;
            set;
        }

        private BuildTreeItemNode ParentNode
        {
            get;
            set;
        }

        private Func<T> ResolutionFunction
        {
            get;
            set;
        }
    }
}

The extension will now have a build tree for the root instance from the example above that has a reference to the lazy loaded dependency. This means that the extension will now correctly tear down the root instance when container.TearDown(root) is invoked. The above example with this fix now writes True to the console for the lazy loaded example.

The updated code for the DisposalStrategyExtension can be found here in my Toolkit project on CodePlex.

Tags: , ,

Jul 23 2010

Caching workflow activities to increase performance

Category: .NetRory Primrose @ 07:14

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.

using System;
using System.Activities;
using System.Collections.Generic;
using System.Threading;
using Neovolve.Toolkit.Threading;

namespace Neovolve.ActivityTesting
{
    internal static class ActivityStore
    {
        private static readonly IDictionary<Type, Activity> _store = new Dictionary<Type, Activity>();

        private static readonly ReaderWriterLockSlim _syncLock = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion);

        public static T Resolve<T>() where T : Activity, new()
        {
            Type activityType = typeof(T);

            using (new LockReader(_syncLock))
            {
                if (_store.ContainsKey(activityType))
                {
                    return _store[activityType] as T;
                }
            }

            using (new LockWriter(_syncLock))
            {
                // Protect the store against mutliple threads that get passed the reader lock
                if (_store.ContainsKey(activityType))
                {
                    return _store[activityType] as T;
                }

                T activity = new T();

                _store[activityType] = activity;

                return activity;
            }
        }
    }
}

This class will hold on to activity instances in a dictionary using the activity type as the key. To use this class you simply need to make a call out to ActivityStore.Resolve<T>() rather than new T() where T is your activity type.

Tags: , , ,

Jul 22 2010

Working with custom proxies

Category: .NetRory Primrose @ 07:56

My recent post about creating proxies with RealProxy provided an example for creating a custom proxy implementation. Using proxies can provide a lot of power and flexibility to an application. Most of this code is common plumbing code that can be refactored out into some reusable classes.

The ProxyHandler class below is the first of these reusable classes. It helps with creating RealProxy types by providing the common logic of method identification, exception processing and method response management. It also provides the support for a derived proxy implementation to leverage some initialization logic provided by the calling application. It uses a MethodResolver class from my Toolkit project to identify the method to invoke on the proxy.

using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Proxies;
using System.Security.Permissions;
using Neovolve.Toolkit.Reflection;

namespace Neovolve.Toolkit.Communication
{
    public abstract class ProxyHandler<T> : RealProxy where T : class
    {
        protected ProxyHandler()
            : base(typeof(T))
        {
        }

        public virtual void Initialize<TInitialize>(Action<TInitialize> action)
        {
            InitializeAction = action;
        }

        [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
        [DebuggerStepThrough]
        public override IMessage Invoke(IMessage msg)
        {
            Debug.Assert(msg != null, "No message has been provided");

            ReturnMessage responseMessage;
            Object response = null;
            Exception caughtException = null;

            try
            {
                String methodName = (String)msg.Properties["__MethodName"];
                Type[] parameterTypes = (Type[])msg.Properties["__MethodSignature"];
                MethodBase method = MethodResolver.Resolve(typeof(T), methodName, parameterTypes);

                Debug.Assert(method != null, "Method was not found on the proxy");

                Object[] parameters = (Object[])msg.Properties["__Args"];

                // Invoke the action
                response = ExecuteMethod(method, parameters);
            }
            catch (Exception ex)
            {
                // Store the caught exception
                caughtException = ex;
            }

            IMethodCallMessage message = msg as IMethodCallMessage;

            // Check if there is an exception
            if (caughtException == null)
            {
                // Return the response from the service
                responseMessage = new ReturnMessage(response, null, 0, null, message);
            }
            else
            {
                // Return the exception thrown by the service
                responseMessage = new ReturnMessage(caughtException, message);
            }

            // Return the response message
            return responseMessage;
        }

        protected abstract Object ExecuteMethod(MethodBase method, Object[] parameters);

        protected MulticastDelegate InitializeAction
        {
            get;
            set;
        }
    }
}

The ProxyManager class below encapsulates the creation and lifetime management of a ProxyHandler instance. It creates a proxy instance from the ProxyHandler when the Proxy property is referenced and disposes the proxy when the ProxyManager is disposed. It has some logic for attempted to resolve a ProxyHandler<T> or then falling back on a default proxy or a proxy to a WCF channel if no ProxyHandler is provided in its constructor.

using System;
using System.Diagnostics;
using System.Linq;
using System.ServiceModel;
using Neovolve.Toolkit.Reflection;

namespace Neovolve.Toolkit.Communication
{
    public class ProxyManager<T> : IDisposable where T : class
    {
        private T _proxy;

        public ProxyManager()
        {
            if (TypeResolver.CanResolveType(typeof(ProxyHandler<T>)))
            {
                ProxyHandler = TypeResolver.Create<ProxyHandler<T>>();
            }
            else
            {
                // Check if T is a service contract
                Object serviceContract = typeof(T).GetCustomAttributes(true).Where(x => x is ServiceContractAttribute).FirstOrDefault();

                if (serviceContract != null)
                {
                    // This is a service contract, default to using the WCF proxy handler
                    ProxyHandler = new ChannelProxyHandler<T>();
                }
                else
                {
                    // No proxy handler is known for this type
                    ProxyHandler = new DefaultProxyHandler<T>();
                }
            }
        }

        public ProxyManager(ProxyHandler<T> proxyHandler)
        {
            ProxyHandler = proxyHandler;
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(Boolean disposing)
        {
            if (disposing)
            {
                // Free managed resources
                if (Disposed == false)
                {
                    Disposed = true;

                    IDisposable disposableHandler = ProxyHandler as IDisposable;

                    if (disposableHandler != null)
                    {
                        disposableHandler.Dispose();
                    }

                    ProxyHandler = null;
                    Proxy = null;
                }
            }

            // Free native resources if there are any.
        }

        public T Proxy
        {
            get
            {
                if (Disposed)
                {
                    throw new ObjectDisposedException(GetType().FullName);
                }

                if (_proxy == null)
                {
                    // Create a channel from the handler
                    _proxy = (T)ProxyHandler.GetTransparentProxy();

                    Debug.Assert(_proxy != null, "The proxy handler failed to create the proxy.");
                }

                return _proxy;
            }

            private set
            {
                _proxy = value;
            }
        }

        public ProxyHandler<T> ProxyHandler
        {
            get;
            private set;
        }

        protected Boolean Disposed
        {
            get;
            set;
        }
    }
}

These classes work together to make it really easy to work with custom proxies. The most common usage I have for these classes is to proxy a call out to a WCF service. The following is an example of how this looks in a client console application. The benefit here for working with WCF is that all the management of WCF channels is abstracted away from the application code.

using System;
using System.ServiceModel;
using Neovolve.Toolkit.Communication;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            using (ProxyManager<ITestService> manager = new ProxyManager<ITestService>())
            {
                String result = manager.Proxy.DoSomething("Service input data");

                Console.WriteLine("Result from service is: " + result);
            }

            Console.ReadKey();
        }
    }

    [ServiceContract]
    public interface ITestService
    {
        [OperationContract]
        String DoSomething(String data);
    }
}

The code for these classes can be found in my Neovolve.Toolkit project out on CodePlex.

Tags: ,

Jul 20 2010

Unity Injection With ASP.Net and WCF - Presentation deck and code

Category: .Net | IT RelatedRory Primrose @ 08:25

Yesterday I ran a couple of sessions at the Canberra .Net users group. I have attached a zip of the presentation deck and demo projects for you to have a look at in your own time.

Unity Injection With ASP.Net and WCF.zip (1.45 mb)

Tags: , , , ,

Jul 18 2010

Speaking at CodeCampOz

Category: IT Related | .Net | ApplicationsRory Primrose @ 04:19

Mitch has just posted the agenda for CodeCampOz that is running in November. Looks like it will be a really good mix of information being presented this year.

I’ll be running a session on Windows Identity Framework and how to use it without federation. Here is the abstract for my session.

Not a WIF of federation

The Windows Identify Framework (WIF) provides the latest Microsoft implementation for working in the claims-based identity space. WIF has particular strengths in providing federated security for systems that target users across multiple security domains, multiple credential types and multiple credential stores.

Unfortunately the available WIF documentation and samples almost completely deal with federated security scenarios. The information provided continues to use federated security architectures (Security Token Services, Issuing Authorities, Relying Parties etc.) even when federation is not used.

Developers of small systems may find it difficult to understand how WIF fits into their system designs. Small systems in this context tend to have their own security store, do not cross security domains and may not even run within an Active Directory managed domain.

There are clear benefits with using claims based security in both large and small systems. How do developers leverage claims-based security without being tied to federated security architectures?

This session will briefly cover the benefits of claims-based security and then look at how to implement WIF in ASP.Net and WCF applications without federation dependencies.

Tags: , , ,

Jul 17 2010

Creating proxies with RealProxy

Category: .NetRory Primrose @ 14:53

I first came across the RealProxy class three years ago when trying to figure out better ways of handling WCF client proxies (correct connection disposal, reusing faulted channels etc). I was intrigued about how ChannelFactory<T> could return an instance of a service contract that had the implementation of a WCF client for an interface definition it knows nothing about.

With a decent amount of Reflector surfing I followed the rabbit hole down to the usage of RealProxy. In my opinion this has to be one of the most interesting classes in the CLR. I finally founds some time to post some information about this amazing class.

Imagine a scenario where you want to have an action that you want to take when a method on a type is invoked when you do not have any prior knowledge of the type definition. The RealProxy class is able to run some magic that will return you a proxy instance of that type and provide notification when method invocations occur on that proxy. The main downside with RealProxy is that the type to proxy must either be an interface or a class that inherits from MarshalByRefObject.

The following is an example of a RealProxy implementation that outputs method invocations to the console.

public class TestProxy<T> : RealProxy
{
    public TestProxy()
        :base(typeof(T))
    {
    }

    [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
    [DebuggerStepThrough]
    public override IMessage Invoke(IMessage msg)
    {
        Debug.Assert(msg != null, "No message has been provided");

        ReturnMessage responseMessage;
        Object response = null;
        Exception caughtException = null;

        try
        {
            String methodName = (String)msg.Properties["__MethodName"];
            Type[] parameterTypes = (Type[])msg.Properties["__MethodSignature"];
            MethodBase method = typeof(T).GetMethod(methodName, parameterTypes);

            Object[] parameters = (Object[])msg.Properties["__Args"];

            // ______________________________________________________________________________
            //
            // Start the logic for handling the method invocation on this proxy
            // ______________________________________________________________________________

            Console.WriteLine("Invoking " + method.Name + " with the following parameters:");

            for (int index = 0; index < parameters.Length; index++)
            {
                Console.WriteLine(parameterTypes[index].Name + " - " + parameters[index]);
            }

            // ______________________________________________________________________________
            //
            // End the logic for handling the method invocation on this proxy
            // ______________________________________________________________________________
        }
        catch (Exception ex)
        {
            // Store the caught exception
            caughtException = ex;
        }

        IMethodCallMessage message = msg as IMethodCallMessage;

        // Check if there is an exception
        if (caughtException == null)
        {
            // Return the response from the service
            responseMessage = new ReturnMessage(response, null, 0, null, message);
        }
        else
        {
            // Return the exception thrown by the service
            responseMessage = new ReturnMessage(caughtException, message);
        }

        // Return the response message
        return responseMessage;
    }
}

The class informs RealProxy about the type to proxy when it calls the base constructor. Invocations of the proxy methods cause the Invoke method to be called. The Invoke parameters provide information about the method name, parameter types and parameter values for the method invocation on the proxy instance. The Invoke method handles any exceptions so that they can be processed correctly by the proxy and be correctly thrown in the calling code. A return value (or null for void methods) are processed in the return message if no exception was found.

The key for working with a RealProxy instance is how the proxy is created. The proxy instance is not the class that inherits from RealProxy. That class is simply runs the processing of methods called on the proxy instance. The proxy instance is actually created from the RealProxy class using the GetTransparentProxy() method.

The following is a console application that uses an interface definition to test the above proxy implementation.

class Program
{
    static void Main(string[] args)
    {
        TestProxy<ITester> proxy = new TestProxy<ITester>();
        ITester tester = proxy.GetTransparentProxy() as ITester;

        tester.RunTest("This is the message", true, Guid.NewGuid());

        Console.ReadKey();
    }
}

public interface ITester
{
    void RunTest(String message, Boolean flag, Guid marker);
}

This console application uses the TestProxy<T> class to create a proxy for the ITester interface. Invocations of the proxy instance then cause TestProxy<T>.Invoke to process the invocation. TestProxy in this case will output information about the method invocation to the console. The output for this example is something like the following.

Invoking RunTest with the following parameters:
String - This is the message
Boolean - True
Guid - aade8728-9ca3-4919-9080-14090b5b016b

That’s all there is to it for rolling your own proxy implementation.

Tags: ,

Jul 12 2010

UnityServiceBehavior updated to support named resolutions

Category: .NetRory Primrose @ 17:43

I previously posted about how to get Unity support in WCF services via a ServiceBehavior. I found a glaring omission in this implementation when preparing for my .Net Users Group presentation. The existing code supports named configuration sections and named containers. Unfortunately it left out the more common named instance resolutions.

I have checked in a new code version that supports this. See UnityServiceElement, UnityServiceBehavior and UnityInstanceProvider for the updated code line.

Tags: , ,