Uncategorized

Azure Configuration and Castle Windsor Singletons

In my previous post, we showed how you can update Azure configuration when settings may not be accessed again after changes are made.  Castle Windsor is a great framework for providing Dependency Injection, and in order to maintain testability of your classes, azure settings should be injected so they can be tested independently of Azure.

But what happens when configuration changes are made?  If these are injected in, and the class that uses them has been set up as a singleton, these changes will not get applied until a restart of the application.  In order to fix this we can tell Castle to refresh and recreate its singleton classes after configuration changes are made.  Normally Singletons are set up in Windsor as

     
container.Register(Component.For().ImplementedBy().LifestyleSingleton());

Castle Windsor allows you to create your own custom lifestyle manager. We can inherit from the existing Singleton provider and tell it to reset whenever there are configuration changes:

namespace FooBar.Plumbing
{
    using Castle.MicroKernel.Lifestyle;

    using Microsoft.WindowsAzure.ServiceRuntime;

    public class AzureSingletonLifestyleManager : SingletonLifestyleManager
    {
        public AzureSingletonLifestyleManager()
        {
            RoleEnvironment.Changed += this.RoleEnvironment_Changed;
        }

        private void RoleEnvironment_Changed(object sender, RoleEnvironmentChangedEventArgs e)
        {
            this.Dispose();
        }
    }
}

this.Dispose() tells the singleton manager to reset, and the next request for a class will be recreated, with any new configuration changes (this.Dispose() is not from IDisposable, but Castle have just given the method the same name).

In order to use this in our installers we can use:

container.Register(Component.For().ImplementedBy<MySearchProvider().LifestyleCustom());

Or we can create an extension method to make this a bit cleaner:

public static ComponentRegistration LifestyleAzureSingleton(this ComponentRegistration registration) where TService : class
        {
            if (registration == null)
            {
                throw new ArgumentNullException("registration");
            }
 
            return registration.LifestyleCustom();
        }

Beware though. You need to make sure that and configuration settings that you retrieved, are retrieved in the instantiated class (e.g. in the constructor). Otherwise even though castle will recreate your object, the setting that will be passed in will be the initial (non-updated) value

Leave a Reply

Your email address will not be published. Required fields are marked *