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: ,

Jul 12 2010

Canberra .Net Users Group Presentation next week

Category: .Net | ApplicationsRory Primrose @ 17:32

I’m going to be presenting at this months .Net Users Group in Canberra. The topic will be Unity injection for ASP.Net and WCF with some Unity extensibility added in as well.

Here is the abstract for the session.

Unity is the Microsoft Patterns and Practises implementation of an inversion of control (IoC) container. Using IoC containers facilitates the dependency injection pattern which helps to decouple code from its dependencies.

A common way to implement IoC in ASP.Net and WCF services is to couple the hosted application to the IoC container. The first half of this session will look at how ASP.Net and WCF applications can be extended to leverage the benefits of IoC while decoupling the hosted application from the container.

The second half of the session will look at how Unity can be extended to provide a recursive disposal pattern for build trees created by the container.

If you are local then I hope to see you there.

Tags: , , , ,

Jul 7 2010

Unity build failure recovery for DisposableStrategyExtension

Category: .Net | ApplicationsRory Primrose @ 17:41

I posted recently about my Unity extension that disposes build trees when a container tears down an instance it previously created. The extension makes an assumption that a Unity build operation will either succeed completely or fail completely. Normally you expect this to be the case. I have however now come up with an edge case.

I am writing another Unity extension that adds support for injecting proxy instances as dependencies. Part of this design allows for custom proxy handlers to be injected. Defining a custom proxy handler is optional and can either be specifically defined in configuration at the injection definition or be automatically resolved by the Unity container from contextual information. If a custom proxy isn’t defined or can’t be automatically resolved then the injection will fall back to a default proxy handler type.

This new extension creates a child build context within the build context of the proxy dependency being created by the Unity container. The child build context will attempt to create the proxy handler just in case the container is configured for it. Unity will throw an exception if the proxy handler isn’t defined. In this case however, the build operation needs to continue rather than failing like you would normally expect.

This becomes a problem for the DisposableStrategyExtension. It tracks build trees as they are created using the BuildTreeTracker class mentioned in the previous post. It tracks when a new build context is started and when it is finished. Each iteration of this process tracks the current tree node being built by the context. Each child build context encountered results in a new child node that is simply added to the current node. The child node then becomes tracked as the current node being built. Unfortunately there is no fault tolerance for when an item fails to be built when the overall build operation can continue.

Consider the following build tree for example.

  • Root
    • ChildA
      • DependencyA
      • DependencyB
    • ChildB

The PreBuildUp method in BuildTreeTracker gets invoked before each tree node is created and PostBuildUp gets invoked after each node (and it’s children) are completely built. The BuildTreeTracker class tracks the start and end of each item being built via these two methods. What happens if the creation of ChildA fails without any recovery action? Assuming the build process handles the build failure exception and continues the build, the BuildTreeTracker identifies the current node as ChildA when it goes to create ChildB (PreBuildUp) however it should actually point to Root. This is because the tracker re-points the current node in the build tree back to the parent of the current node on PostBuildUp. Unfortunately PostBuildUp does not get invoked when a build context fails.

Enter the IRequiresRecovery interface. This interface allows for some recovery operation to be invoked when a build context has failed to create an instance.

using System;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using Microsoft.Practices.ObjectBuilder2;

namespace Neovolve.Toolkit.Unity
{
    internal class BuildTreeRecovery : IRequiresRecovery
    {
        public BuildTreeRecovery(IBuilderContext context, BuildTreeItemNode failedNode, Action<BuildTreeItemNode> failureAction)
        {
            Contract.Requires<ArgumentNullException>(context != null, "The context parameter is null");
            Contract.Requires<ArgumentNullException>(failedNode != null, "The failedNode parameter is null");

            Context = context;
            FailedNode = failedNode;
            FailureAction = failureAction;
        }

        public void Recover()
        {
            try
            {
                if (FailureAction != null)
                {
                    FailureAction(FailedNode);
                }

                BuildTreeItemNode parentNode = FailedNode.Parent;

                BuildTreeDisposer.DisposeTree(Context, FailedNode);

                if (parentNode != null)
                {
                    parentNode.Children.Remove(FailedNode);
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine("Recovery failed: " + ex);
            }
        }

        protected IBuilderContext Context
        {
            get;
            private set;
        }

        protected BuildTreeItemNode FailedNode
        {
            get;
            private set;
        }

        protected Action<BuildTreeItemNode> FailureAction
        {
            get;
            private set;
        }
    }
}

The BuildTreeRecovery class allows for a custom action to be invoked. It then cleans up any partial build trees that were successfully created under the failed node and then removes it from its parent. If you assume in the previous example that DependencyA and DependencyB were successfully created before ChildA failed, then BuildTreeRecovery will ensure that ChildA, DependencyA and DependencyB are all disposed and that the failed node (ChildA) is then removed from the build tree.

The final piece missing here is that the BuildTreeTracker class will still have a reference to ChildA being the current node instead of Root when PreBuildUp is invoked for ChildB. This is where the custom action of the recovery class comes in. The BuildTreeTracker.PreBuildUp method has been updated to create the BuildTreeRecovery class and use it in a recovery stack. The action passed to its constructor is a lambda expression that repairs the assignment of the current node in the build tree to be the parent of the failed node.

public override void PreBuildUp(IBuilderContext context)
{
    base.PreBuildUp(context);

    if (context == null)
    {
        return;
    }

    Boolean nodeCreatedByContainer = context.Existing == null;
    BuildTreeItemNode newTreeNode = new BuildTreeItemNode(context.BuildKey, nodeCreatedByContainer, CurrentBuildNode);

    if (CurrentBuildNode != null)
    {
        // This is a child node
        CurrentBuildNode.Children.Add(newTreeNode);
    }

    CurrentBuildNode = newTreeNode;

    BuildTreeRecovery recovery = new BuildTreeRecovery(context, newTreeNode, failedNode => CurrentBuildNode = failedNode.Parent);

    context.RecoveryStack.Add(recovery);
}

Completing the example proposed above, the resultant build tree when ChildA fails to build would be:

  • Root
    • ChildB

While using this recovery class satisfies my optional build requirement for proxy injection, it provides an arguably more important feature. Build trees might fail at anytime and applications may recover from or simply ignore the failures and continue. The partial build trees created in these attempts may have created some references that require disposal but this can never occur because the original BuildTreeTracker code would simply lose track of nodes successfully created in a failed build tree. This solution will ensure that these instances are disposed immediately if the build operation fails.

Tags:

Jul 5 2010

ConnectionStringSettings parameter injection in Unity

Category: Rory Primrose @ 18:15

I have previously posted about supporting AppSetting value resolution for Unity injection (Unity 1.x here and Unity 2.0 here). Today I had a requirement to inject connection string values from application configuration. Like the AppSetting implementation, this creates a nice redirection of injection values as developers and administrators are more familiar with the connection string section in application configuration compared to finding the right value in large amounts of Unity configuration.

This implementation leverages the AppSettingParameterValueExtension class from the prior examples and renames it to SectionExtensionInitiator. This class now configures a Unity section for multiple element extensions rather than a single specific implementation.

using Microsoft.Practices.Unity.Configuration;

namespace Neovolve.Toolkit.Unity
{
    public class SectionExtensionInitiator : SectionExtension
    {
        public override void AddExtensions(SectionExtensionContext context)
        {
            if (context == null)
            {
                return;
            }
 
            context.AddElement<AppSettingsParameterValueElement>(AppSettingsParameterValueElement.ElementName);
            context.AddElement<ConnectionStringParameterValueElement>(ConnectionStringParameterValueElement.ElementName);
        }
    }
}

The ConnectionStringParameterValueElement is responsible for creating an injection value for a parameter. It can be used to create a parameter for either the String or ConnectionStringSettings types.

using System;
using System.Configuration;
using System.Globalization;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
using Neovolve.Toolkit.Storage;
using Neovolve.Toolkit.Unity.Properties;

namespace Neovolve.Toolkit.Unity
{
    public class ConnectionStringParameterValueElement : ParameterValueElement
    {
        public const String ElementName = "connectionSetting";

        public ConnectionStringParameterValueElement()
        {
            Config = ConfigurationStoreFactory.Create();
        }

        public ConnectionStringSettings CreateValue()
        {
            ConnectionStringSettings configurationValue = Config.GetConnectionSetting(ConnectionStringKey);

            if (configurationValue == null)
            {
                String message = String.Format(CultureInfo.InvariantCulture, Resources.ConnectionStringParameterValueElement_ConnectionStringKeyNotFound, ConnectionStringKey);

                throw new ConfigurationErrorsException(message);
            }

            return configurationValue;
        }

        public override InjectionParameterValue GetInjectionParameterValue(IUnityContainer container, Type parameterType)
        {
            if (parameterType == null)
            {
                throw new ArgumentNullException("parameterType");
            }

            ConnectionStringSettings injectionValue = CreateValue();

            if (parameterType.Equals(typeof(String)))
            {
                return new InjectionParameter(parameterType, injectionValue.ConnectionString);
            }
            
            if (parameterType.Equals(typeof(ConnectionStringSettings)))
            {
                return new InjectionParameter(parameterType, injectionValue);
            }

            String message = String.Format(CultureInfo.InvariantCulture, Resources.ConnectionStringParameterValueElement_InvalidParameterType, parameterType.FullName);

            throw new InvalidOperationException(message);
        }

        [ConfigurationProperty("connectionStringKey", IsRequired = true)]
        public String ConnectionStringKey
        {
            get
            {
                return (String)base["connectionStringKey"];
            }

            set
            {
                base["connectionStringKey"] = value;
            }
        }

        private IConfigurationStore Config
        {
            get;
            set;
        }
    }
}

Usually a string parameter would be used as the injection type. This will then decouple the dependency from the System.Configuration assembly. The only time that the ConnectionStringSettings class should be used as the injection parameter type is when the provider information on the connection string configuration is required for some application logic.

The Unity configuration needs to be set up with the SectionExtensionInitiator class to support connection string injection. A connectionString element can then be used to define a connection string injection value.

<?xml version="1.0"
      encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="unity"
             type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
  </configSections>
  <connectionStrings>
    <add name="TestConnection" connectionString="Data Source=localhost;Database=SomeDatabase;Integrated Security=SSPI;"/>
  </connectionStrings>
  <unity>
    <sectionExtension type="Neovolve.Toolkit.Unity.SectionExtensionInitiator, Neovolve.Toolkit.Unity" />
    <containers>
      <container>
        <register type="Neovolve.Toolkit.Unity.IntegrationTests.IDoSomething, Neovolve.Toolkit.Unity.IntegrationTests"
                  mapTo="Neovolve.Toolkit.Unity.IntegrationTests.ConnectionTest, Neovolve.Toolkit.Unity.IntegrationTests"
                  name="ConnectionStringTesting">
          <constructor>
            <param name="connectionString">
              <connectionSetting connectionStringKey="TestConnection" />
            </param>
          </constructor>        
        </register>
      </container>
    </containers>
  </unity>
</configuration>

This configuration will resolve a connection string with the name TestConnection and inject it into the constructor of the ConnectionTest class.

All the code and documentation for this implementation is in my Toolkit project on CodePlex.

Tags: