My colleague Simon Evans and I recently presented at the UK Azure .Net user group in London about a project that we have just delivered. The project is a 100% cloud solution, running in Windows Azure web roles and making use of Azure Table and Blob Storage and SQL Azure. Whilst development on the project is complete, the site is not yet live to the public, but will be soon, which will enable me to talk more freely on this subject.

A few of the implementation specific details that we talked about in the presentation focussed on how we kept the footprint of Azure as small as possible within our solution. I explained why this is a good idea and how it can be achieved, so for those who don’t want to watch the video, here’s the write-up…

Working with the Dev Fabric

The Windows Azure SDK comes with the Dev Fabric, which is a simulation of the Azure platform that allows developers to run Azure solutions locally on their developer machines. It simulates the web and worker roles and also the various storage sources – table, blob and queue so that the entire solution can be run as-is on a single machine. Of course, this is just a simulation, and doesn’t provide any of the benefits that the real production Azure platform gives but it is a vital tool in being able to develop for the platform.

However, the Dev Fabric gets in the way of rapid development. Running in the Dev Fabric involves hitting F5 in Visual Studio which builds the solution, packages the solution, deploys the packaged solution, starts up the virtual environment, starts the storage services, loads the browser and finally loads the the site. This whole process, which Visual Studio orchestrates, can take a number of minutes, depending on the size of your solution and the spec of your machine.

A build in Visual Studio is not enough to see your changes. My development process of running all unit tests, seeing a green light, refreshing the browser to make sure my application still hangs together and I haven’t broken any UI logic now has a massive extra step which adds friction to the process. Even more so if all you changed was one line of HTML, or CSS – remember all these files form part of the deployed solution and so every time they change they need to get packaged up and copied somewhere else. Saving a file and hitting refresh in a browser is not going to work!

So, right from day one, I was looking to find ways to run our solution without depending on the Dev Fabric. This may seem slightly backwards – that I was building a cloud solution that would run outside the cloud, but reducing this overhead in the development process – a small one – but one that would happen numerous times a day meant we were able to deliver our project on time.

Interestingly, whilst the primary goal was breaking the dependency on the Azure platform to remove friction during the development process, the result is a well architected solution that has a minimal Azure footprint. Not only does this allow for greater flexibility down the line, but also means that a team with minimal Azure development experience can work effectively in an Azure solution as the necessary implementation specific knowledge is encapsulated in just a few places.

Data Access and the Repository Pattern

I tend to follow a similar pattern when building applications of having an Infrastructure or Data layer that deals with data access or any hard dependencies on external services. My friends Howard and Jon and I have talked a lot about this in the Who Can Help Me? project, which provides an architectural showcase for an MVC web application, building on top of the Sharp Architecture project. By adhering to these same patterns, we were able to encapsulate all our data access into repositories which dealt with our domain entities when reading and writing. This meant that our entire application has no concept of where these entities are stored until you get into the repository itself.

As Martin Fowler writes:

“A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection. Client objects construct query specifications declaratively and submit them to Repository for satisfaction. Objects can be added to and removed from the Repository, as they can from a simple collection of objects, and the mapping code encapsulated by the Repository will carry out the appropriate operations behind the scenes. Conceptually, a Repository encapsulates the set of objects persisted in a data store and the operations performed over them, providing a more object-oriented view of the persistence layer. Repository also supports the objective of achieving a clean separation and one-way dependency between the domain and data mapping layers.”

So, in our case we were able to encapsulate all the Azure Table Storage specific logic inside the repository; we actually took this one step further and encapsulated specific queries into Commands which we could reuse across repositories if necessary.

Dependency Injection and stub Repositories

However, whilst keeping the Azure footprint small, this didn’t break the dependency on data access. In order to run the application we needed to retrieve data, which made calls into Table Storage, which meant we still needed the Dev Fabric to be running.

So… as our repositories all inherit from interfaces and are injected at runtime using the Castle Windsor IOC container, we were able to create stub implementations of these repositories which we could choose to inject instead, meaning we could run the application without the Dev Fabric. This becomes incredibly useful if you’re not actually concerned with the actual data that is being displayed at that point – e.g. you’re building validation logic, or the UI interactions etc.

We use the Fluent Registration feature of Castle Windsor which allows us to register dependencies based on a convention over configuration approach – finding components based on their namespace and location in this case. Rather than have to manually configure the solution to decide whether to use the ‘real’ table storage repositories, or the stub repositories, I wanted this to ‘just work’.

This was achieved by checking the RoleEnvironment.IsAvailable flag that is part of the Azure ServiceRuntime API. The code below shows how we change our conventions for registration based on this knowledge – so, if we’re running in the Dev Fabric (or the live Azure service) we get our real repositories, otherwise we get our stubs.

For more information on using the fluent registration approach, take a look at the Who Can Help Me? project.

public void Register(IWindsorContainer container)
{
    var repositoryNamespace = ".Repositories";

    if (!RoleEnvironment.IsAvailable)
    {
        // If running outside role/dev fabric
        // then use stub repositories
        repositoryNamespace = ".Stub";
        Trace.WriteLine("RUNNING OUTSIDE OF AZURE ROLE - STARTING UP WITH STUB REPOSITORIES");
    }

    container.Register(
        AllTypes.Pick()
            .FromAssembly(Assembly.GetAssembly(typeof(InfrastructureRegistrarMarker)))
            .If(f => f.Namespace.Contains(repositoryNamespace))
            .WithService.FirstNonGenericCoreInterface("SeeTheDifference.Domain.Contracts.Repositories"));
}

Configuration

The Azure environment changes the game slightly when it comes to application configuration as the web.config no longer provides the ability to change configuration at runtime. The reason behind this is that the web.config is packaged up and deployed just like any other code asset as part of your Azure deployment, which means that in order to change a value, you have to go through this whole process again.

The Azure environment does provide another source of configuration in the form of the .cscfg file, which is the Cloud Service Configuration and governs the details about your web or worker roles e.g. number of instances, endpoints, connection strings for Azure data stores. It can also be used to store any custom configuration settings in the form of key-value pairs, similar to the App Settings section you would find in a normal web.config.

So, the recommended approach is to use the .cscfg for any environment specific values as these can then be changed at runtime, which would cause your Azure roles to recycle without re-deployment, just like changing the web.config would in a normal IIS setup.

However, the downside to using the .cscfg is that Azure configuration is only available when the role environment is running – i.e. your using the Dev Fabric. Once again we wanted to break this dependency and be able to run our application outside of this environment.

The approach we took was twofold:

Firstly we encapsulated all our configuration calls into one place – a configuration manager that was injected into any class that needed information from configuration. By doing this we could implement a global switch to check whether we were running inside an Azure environment (just like when we decided which repositories to register) and act accordingly.

Secondly,  we chose to duplicate all our custom configuration settings in .cscfg into our web.config App Settings and read from the appropriate source, according to the RoleEnvironment.IsAvailable flag:

/// <summary>
/// Gets a named configuration setting from application configuration.
/// </summary>
/// <param name="name">The name of configuration setting.</param>
/// <returns></returns>
public string GetSetting(string name)
{
    if (RoleEnvironment.IsAvailable)
    {
        return RoleEnvironment.GetConfigurationSettingValue(name);
    }

    return ConfigurationManager.AppSettings[name];
}

Diagnostics

The Azure diagnostics are key to monitoring how your application is performing and are really the only way to know where and when you need to scale your application out or in. They’re also the source of information for events and custom tracing.

The documentation for configuring the Azure tracing recommends that you add the following configuration to your application’s web.config (and in fact, adds this automatically if you use the role project templates):

<system.diagnostics>
    <trace>
        <listeners>
            <add type="Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener, Microsoft.WindowsAzure.Diagnostics, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                name="AzureDiagnostics">
                <filter type="" />
            </add>
        </listeners>
    </trace>
</system.diagnostics>

The problem here is that we’re tightly coupled again to the role environment, and as this configuration gets loaded and read at application startup, you’re not going to get very far if you’re not running within an Azure environment.

We chose to remove this configuration and add the trace listener programmatically at application startup, after performing the same check on the RoleEnvironment.IsAvailable:

/// <summary>
/// Initialises the Azure diagnostics tracing
/// </summary>
public void Initialise()
{
    if (RoleEnvironment.IsAvailable)
    {
        Trace.Listeners.Add(new DiagnosticMonitorTraceListener());
    }
}

This means that our Azure diagnostics tracing is now only initialised if we need it, meaning we can run without it when we’re in a normal ISS set up.

Summary

Hopefully this has shown that developing an Azure application does not have to be a process that takes over your entire solution and forces you down a particular style of development.

By architecting your solution well you can minimise the footprint that Azure has within your solution, which means that it’s easy to break the dependencies if required.

Being able to run an application in a normal IIS setup, without the Dev Fabric speeds up the development process, especially for those working higher up the stack and dealing solely with UI and presentation logic.

Using RoleEnvironment.IsAvailable to determine whether your running “in the cloud” or not allows you to act accordingly if you want to provide alternative scenarios.

By reducing the footprint of Azure within the solution, inexperienced teams can work effectively and acquire the Azure specific knowledge as and when required.