Web Site Moved to Octopress

If you’re reading this, you may have noticed that I have migrated my web site / blog from Wordpress to Octopress. I had to manually update some of the posts, and it took a day or so for the comments to become available in Disqus, otherwise it was pretty painless. The orginal URLs should be redirected to the new ones. If you notice any problems, please let me know.

I guess that means I need to write a blog post or two!

Auto Incrementing Build Number in Xcode 4

I’ve recently been doing a bit of iOS development and have started using HockeyApp for distributing beta versions and collecting crash reports. Hockey requires that your builds have a unique version number, they have a great knowledge base article showing . The only problem I found with their solution was that the file containing the build number needs to exist beforehand. So, here’s an update to the script to create the file if it doesn’t already exist:

1
2
3
4
5
6
7
8
echo "Updating build number..."
if [ "$CONFIGURATION" == "Release" ]; then
    set -o noclobber
    echo "Build file: ${SRCROOT}/buildnumber.xcconfig"
    echo "BUILD_NUMBER = 0" > "${SRCROOT}/buildnumber.xcconfig"
    set +o noclobber
    /usr/bin/perl -pe 's/(BUILD_NUMBER = )(\d+)/$1.($2+1)/eg' -i buildnumber.xcconfig
fi

Also, don’t forget to add the buildnumber.xcconfig file to your .gitignore.

Git Workflow – Branch Per Feature

Description of the git workflow and a branch per feature, extracted from: http://railsapps.github.com/tutorial-rails-prelaunch-signup.html

When you are using git for version control, you can commit every time you save a file, even for the tiniest typo fixes. If only you will ever see your git commits, no one will care. But if you are working on a team, either commercially or as part of an open source project, you will drive your fellow programmers crazy if they try to follow your work and see such “granular” commits. Instead, get in the habit of creating a git branch each time you begin work to implement a feature. When your new feature is complete, merge the branch and “squash” the commits so your comrades see just one commit for the entire feature.

Create a new git branch for this feature:

1
git checkout -b new-feature

The command creates a new branch named “new-feature” and switches to it, analogous to copying all your files to a new directory and moving to work in the new directory (though that is not really what happens with git).

Commit changes to branch e.g.

1
2
git add .
git commit -am "Implements 'new-feature' feature"

Once the new feature is complete, merge the working branch to “master” and squash the commits so you have just one commit for the entire feature:

1
2
3
git checkout master
git merge --squash new-feature
git commit -am "Implements 'new-feature' feature"

You can delete the working branch when you’re done:

1
git branch -D new-feature</pre>

Userland SPI on the BeagleBone With Ubuntu

For a project I’m working on I want to get a BeagleBone talking to a nRF24L01+ module. The first step is to get userland SPI access working on the BeagleBone, and last week I spent some time getting this going. The good news is that Robert C Nelson has merged my patch into his github repo linux-dev and a prebuilt image is available to download. Read on to learn how to build from source and get details of the patch.

Enhanced Query Objects With S#arp Architecture

I’ve been using S#arp Architecture (and the Who Can Help Me structure) on a few projects for a while now and on the whole I’m very happy with it. However, Ayende’s recent post Architecting in the pit of doom: The evils of the repository abstraction layer hit a nerve, and got me thinking that maybe I’ve been applying the services (or tasks) / repository abstraction a bit too liberally. The following day I saw this tweet mentioning @fabiomaulo’s Enhanced Query Object which looks just the ticket to solving this issue. So, I’ve updated my SharpArchitecture-MultiTenant project on GitHub to use enhanced query objects.

In the SharpArchitecture.MultiTenant.Data project I’ve created an NHibernate folder (and namespace) and added a base class for queries that provides access to the ISession (similar to the existing code in the Repository base class):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
using NHibernate;
using SharpArch.Data.NHibernate;

namespace SharpArchitecture.MultiTenant.Data.NHibernate
{
  public class NHibernateQuery
  {
    protected virtual ISession Session
    {
      get
      {
        var factoryKey = SessionFactoryKeyHelper.GetKey(this);
        return NHibernateSession.CurrentFor(factoryKey);
      }
    }
  }
}

As this project is enabled for multi-tenants I’ve also created a marker interface to indicate if the query is tenant specific:

1
2
3
4
namespace SharpArchitecture.MultiTenant.Framework.Contracts
{
  public interface IMultiTenantQuery { }
}

In MultiTenantSessionFactoryKeyProvider, I’ve updated the GetKeyFrom method to test for implementation of the IMultiTenantQuery interface:

1
2
3
4
5
6
7
8
9
10
public string GetKeyFrom(object anObject)
{
  var type = anObject.GetType();
  var isMultiTenant = type.IsImplementationOf&lt;IMultiTenantQuery&gt;() ||
                      type.IsImplementationOf&lt;IMultiTenantRepository&gt;() ||
                      IsRepositoryForMultiTenantEntity(type);
  return isMultiTenant
    ? GetKey()
    : NHibernateSession.DefaultFactoryKey;
}

Now everything is in place to create some queries, so for the list of Customers I’ve created an interface for the query as below:

1
2
3
4
public interface ICustomerListQuery : IMultiTenantQuery
{
  IPagination&lt;CustomerViewModel&gt; GetPagedList(int pageIndex, int pageSize);
}

and an implementation:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class CustomerListQuery : NHibernateQuery, ICustomerListQuery
{
  public IPagination&lt;CustomerViewModel&gt; GetPagedList(int pageIndex, int pageSize)
  {
    var query = Session.QueryOver&lt;Customer&gt;()
      .OrderBy(customer =&gt; customer.Code).Asc;

    var countQuery = query.ToRowCountQuery();
    var totalCount = countQuery.FutureValue&lt;int&gt;();

    var firstResult = (pageIndex - 1) * pageSize;

    CustomerViewModel viewModel = null;
    var viewModels = query.SelectList(list =&gt; list
                            .Select(mission =&gt; mission.Id).WithAlias(() =&gt; viewModel.Id)
                            .Select(mission =&gt; mission.Code).WithAlias(() =&gt; viewModel.Code)
                            .Select(mission =&gt; mission.Name).WithAlias(() =&gt; viewModel.Name))
      .TransformUsing(Transformers.AliasToBean(typeof(CustomerViewModel)))
      .Skip(firstResult)
      .Take(pageSize)
      .Future&lt;CustomerViewModel&gt;();

    return new CustomPagination&lt;CustomerViewModel&gt;(viewModels, pageIndex, pageSize, totalCount.Value);
  }
}

As you can see, this code is using NHibernate projections and transforms to get a list of the required view models, bypassing the need for a data transfer object (DTO) and mappers. This is a trivial example, but in reality the query would be more complex and likely to flatten the object structure.

Now the controller itself can use the query interface to get the paged list of view models:

1
2
3
4
5
6
public ActionResult Index(int? page)
{
  var customers = _customerListQuery.GetPagedList(page ?? 1, DefaultPageSize);
  var viewModel = new CustomerListViewModel { Customers = customers };
  return View(viewModel);
}

I quite like this solution; the unnecessary layers of abstraction are removed and the queries are nicely encapsulated, if anything more complex is required (e.g. multiple data sources) then it is always possible to fall back to the services / repositories style as before.

Multi-tenancy on S#arp Architecture Revisited

Following my previous post some issues were pointed out with the implementation, the main one being that the correct repository implementation was not resolved from an IRepository<T> interface (see the Google Group discussion for more details).

As mentioned in the discussion I have made some minor modifications to S#arp Architecture to solve this problem and better support multi-tenancy. You can see the changes in the pull request, but it looks like they are now included in the latest release.

The changes are very minor, and centre around the introduction of an interface, ISessionFactoryKeyProvider, so that it is possible to get the session factory key without having to use an attribute:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
namespace SharpArch.Data.NHibernate
{
  public interface ISessionFactoryKeyProvider
  {
    /// &lt;summary&gt;
    /// Gets the session factory key.
    /// &lt;/summary&gt;
    /// &lt;returns&gt;&lt;/returns&gt;
    string GetKey();

    /// &lt;summary&gt;
    /// Gets the session factory key.
    /// &lt;/summary&gt;
    /// &lt;param name="anObject"&gt;An optional object that may have an attribute used to determine the session factory key.&lt;/param&gt;
    /// &lt;returns&gt;&lt;/returns&gt;
    string GetKeyFrom(object anObject);
  }
}

I’ve created a default implementation of this interface that just delegates getting the key from the existing SessionFactoryAttribute.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
namespace SharpArch.Data.NHibernate
{
  /// &lt;summary&gt;
  /// Implementation of &lt;see cref="ISessionFactoryKeyProvider" /&gt; that uses
  /// the &lt;see cref="SessionFactoryAttribute" /&gt; to determine the session
  /// factory key.
  /// &lt;/summary&gt;
  public class DefaultSessionFactoryKeyProvider : ISessionFactoryKeyProvider
  {
    public string GetKey()
    {
      return NHibernateSession.DefaultFactoryKey;
    }

    /// &lt;summary&gt;
    /// Gets the session factory key.
    /// &lt;/summary&gt;
    /// &lt;param name="anObject"&gt;An object that may have the &lt;see cref="SessionFactoryAttribute"/&gt; applied.&lt;/param&gt;
    /// &lt;returns&gt;&lt;/returns&gt;
    public string GetKeyFrom(object anObject)
    {
      return SessionFactoryAttribute.GetKeyFrom(anObject);
    }
  }
}

I’ve also added a helper class SessionFactoryKeyHelper:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using SharpArch.Core;

namespace SharpArch.Data.NHibernate
{
  public static class SessionFactoryKeyHelper
  {
    public static string GetKey()
    {
      var provider = SafeServiceLocator&lt;ISessionFactoryKeyProvider&gt;.GetService();
      return provider.GetKey();
    }

    public static string GetKey(object anObject)
    {
      var provider = SafeServiceLocator&lt;ISessionFactoryKeyProvider&gt;.GetService();
      return provider.GetKeyFrom(anObject);
    }
  }
}

Now whenever S#arp Architecture requires a session factory key we can use the helper class, rather than using SessionFactoryAttribute e.g. in the Repository implementation the code is changed from:

1
2
3
4
5
6
protected virtual ISession Session {
  get {
    string factoryKey = SessionFactoryAttribute.GetKeyFrom(this);
    return NHibernateSession.CurrentFor(factoryKey);
  }
}

to:

1
2
3
4
5
6
protected virtual ISession Session {
  get {
    string factoryKey = SessionFactoryKeyHelper.GetKey(this);
    return NHibernateSession.CurrentFor(factoryKey);
  }
}

Note: this change to the Repository implementation means that the MultiTenantRepository class from my previous post is no longer required.

Similar changes are also made to TransactionAttribute and EntityDuplicateChecker.

If you do not need multi-tenancy, or are happy to use the existing TransactionAttribute to specify the session factory key, then you just need to register the DefaultSessionFactoryKeyProvider implementation in the container:

1
2
3
container.AddComponent("sessionFactoryKeyProvider", 
  typeof(ISessionFactoryKeyProvider),
  typeof(DefaultSessionFactoryKeyProvider));

But if you want to provide the session factory key by any other means, it is just a case of implementing and registering your implementation of ISessionFactoryKeyProvider.

In my sample application I’ve implemented it as below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
using System;
using System.Linq;
using SharpArch.Data.NHibernate;
using SharpArchitecture.MultiTenant.Framework.Contracts;
using SharpArchitecture.MultiTenant.Framework.Extensions;
using SharpArchitecture.MultiTenant.Framework.Services;

namespace SharpArchitecture.MultiTenant.Framework.NHibernate
{
  public class MultiTenantSessionFactoryKeyProvider : ISessionFactoryKeyProvider
  {
    private readonly ITenantContext _tenantContext;

    public MultiTenantSessionFactoryKeyProvider(ITenantContext tenantContext)
    {
      _tenantContext = tenantContext;
    }

    public string GetKey()
    {
      var key = _tenantContext.Key;
      return string.IsNullOrEmpty(key) ? NHibernateSession.DefaultFactoryKey : key;
    }

    public string GetKeyFrom(object anObject)
    {
      var type = anObject.GetType();
      return IsMultiTenantRepository(type) || IsRepositoryForMultiTenantEntity(type)
        ? GetKey()
        : NHibernateSession.DefaultFactoryKey;
    }

    public bool IsMultiTenantRepository(Type type)
    {
      return type.IsImplementationOf&lt;IMultiTenantRepository&gt;();
    }

    public bool IsRepositoryForMultiTenantEntity(Type type)
    {
      if (!type.IsGenericType) {
        return false;
      }

      var genericTypes = type.GetGenericArguments();
      if (!genericTypes.Any()) {
        return false;
      }

      var firstGenericType = genericTypes[0];
      return firstGenericType.IsImplementationOf&lt;IMultiTenantEntity&gt;();
    }
  }
}

This makes use of a couple of marker interfaces IMultiTenantEntity and IMultiTenantRepository to decide whether we need to get the tenant, or the default, session factory key. Actually getting the tenant session factory key is accomplished by the implementation of ITenantContext.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
using System.Web;
using SharpArchitecture.MultiTenant.Framework.Services;

namespace SharpArchitecture.MultiTenant.Web.Services
{
  public class TenantContext : ITenantContext
  {
    private const string DefaultStorageKey = "tenant-context-key";

    public string Key
    {
      get
      {
        if (string.IsNullOrEmpty(StoredKey)) {
          StoredKey = KeyFromRequest;
        }
        return StoredKey;
      }

      set { StoredKey = value; }
    }

    public string KeyFromRequest
    {
      get
      {
        var host = HttpContext.Current.Request.Headers["HOST"];
        var domains = host.Split('.');
        return domains.Length &gt;= 3 ? domains[0] : string.Empty;
      }
    }

    protected string StoredKey
    {
      get { return HttpContext.Current.Items[DefaultStorageKey] as string; }
      set { HttpContext.Current.Items[DefaultStorageKey] = value; }
    }
  }
}

I’ve update my sample application on GitHub with these changes and to run against  S#arp Architecture v1.95.

Multi-tenancy on S#arp Architecture Revisited

Update: the code below is out of date, please see Multi-tenancy on S#arp Architecture Revisited for a better solution

Recently I’ve been working on adding multi-tenancy to a web application based on the excellent S#arp Architecture and thought I’d share what I have so far.

This implementation is mainly based on this post from Robert Johnson, and uses a separate database for each tenant, along with a master database to hold the details of the tenants (and anything else you wish). The main drawback with using separate databases is handling the migrations, I haven’t yet got a solution to this but will look at a way of automating it using something like Migrator.Net in a future post.

All of the domain entities inherit from SharpArch.Core.DomainModel.Entity, and I use a marker interface to indicate which entities are part of the tenant domain model.

1
2
3
4
5
6
7
namespace SharpArchitecture.MultiTenant.Core.Contracts
{
  /// &lt;summary&gt;
  /// Marker interface for multi tenant entities.
  /// &lt;/summary&gt;
  public interface IMultiTenantEntity { }
}

We can now create our domain entities for the tenants:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
using NHibernate.Validator.Constraints;
using SharpArch.Core.DomainModel;
using SharpArchitecture.MultiTenant.Core.Contracts;

namespace SharpArchitecture.MultiTenant.Core
{
  public class Customer : Entity, IMultiTenantEntity
  {
    [DomainSignature]
    [NotNullNotEmpty]
    public virtual string Code { get; set; }

    [DomainSignature]
    [NotNullNotEmpty]
    public virtual string Name { get; set; }
  }
}

And we create an entity, to be stored in the master database, to represent each tenant:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
using SharpArch.Core.DomainModel;

namespace SharpArchitecture.MultiTenant.Core
{
  public class Tenant : Entity
  {
    public virtual string Name { get; set; }

    [DomainSignature]
    public virtual string Domain { get; set; }

    public virtual string ConnectionString { get; set; }
  }
}

The application will make use of a separate NHibernate session for each tenant, identified by a key. For the master database the default session will be used. So, we create an interface that will provide access to the key:

1
2
3
4
5
6
7
namespace SharpArchitecture.MultiTenant.Framework.Services
{
  public interface ITenantContext
  {
    string Key { get; set; }
  }
}

And we implement this interface based on the method we choose to identify tenants, in this case based on the subdomain:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
using System.Web;
using SharpArchitecture.MultiTenant.Framework.Services;

namespace SharpArchitecture.MultiTenant.Web.Services
{
  public class TenantContext : ITenantContext
  {
    private const string DefaultStorageKey = "tenant-context-key";

    public string Key
    {
      get
      {
        if (string.IsNullOrEmpty(StoredKey)) {
          StoredKey = KeyFromRequest;
        }
        return StoredKey;
      }

      set { StoredKey = value; }
    }

    public string KeyFromRequest
    {
      get
      {
        var host = HttpContext.Current.Request.Headers["HOST"];
        var domains = host.Split('.');
        return domains.Length &gt;= 3 ? domains[0] : string.Empty;
      }
    }

    protected string StoredKey
    {
      get { return HttpContext.Current.Items[DefaultStorageKey] as string; }
      set { HttpContext.Current.Items[DefaultStorageKey] = value; }
    }
  }
}

If a different method of identifying tenants is required, say by a query string parameter, then it is just a case of providing a different implementation of ITenantContext.

We can now create a multi-tenant repository that uses ITenantContext to select the NHibernate session based on the key:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
using NHibernate;
using SharpArch.Data.NHibernate;
using SharpArchitecture.MultiTenant.Framework.Services;

namespace SharpArchitecture.MultiTenant.Data.Repositories
{
  public class MultiTenantRepository&lt;T&gt; : Repository&lt;T&gt;
  {
    private readonly ITenantContext _tenantContext;

    public MultiTenantRepository(ITenantContext tenantContext)
    {
      _tenantContext = tenantContext;
    }

    protected override ISession Session
    {
      get
      {
        var key = _tenantContext.Key;
        return string.IsNullOrEmpty(key) ? base.Session : NHibernateSession.CurrentFor(key);
      }
    }
  }
}

Next we need to create a repository interface:

1
2
3
4
5
6
7
8
9
10
using MvcContrib.Pagination;
using SharpArch.Core.PersistenceSupport;

namespace SharpArchitecture.MultiTenant.Core.RepositoryInterfaces
{
  public interface ICustomerRepository : IRepository&lt;Customer&gt;
  {
    IPagination&lt;Customer&gt; GetPagedList(int pageIndex, int pageSize);
  }
}

and implementation for our multi-tenant entities:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
using MvcContrib.Pagination;
using NHibernate.Criterion;
using SharpArchitecture.MultiTenant.Core;
using SharpArchitecture.MultiTenant.Core.RepositoryInterfaces;
using SharpArchitecture.MultiTenant.Framework.Services;

namespace SharpArchitecture.MultiTenant.Data.Repositories
{
  public class CustomerRepository : MultiTenantRepository&lt;Customer&gt;, ICustomerRepository
  {
    public CustomerRepository(ITenantContext tenantContext) : base(tenantContext)
    {
    }

    public IPagination&lt;Customer&gt; GetPagedList(int pageIndex, int pageSize)
    {
      var firstResult = (pageIndex - 1) * pageSize;
      var customers = Session.QueryOver&lt;Customer&gt;()
        .OrderBy(customer =&gt; customer.Code).Asc
        .Skip(firstResult)
        .Take(pageSize)
        .Future&lt;Customer&gt;();

      var totalCount = Session.QueryOver&lt;Customer&gt;()
        .Select(Projections.Count&lt;Customer&gt;(customer =&gt; customer.Code))
        .FutureValue&lt;int&gt;();

      return new CustomPagination&lt;Customer&gt;(customers, pageIndex, pageSize, totalCount.Value);
    }
  }
}

Our controllers can now make use of ICustomerRepository without having to worry about any of the multi-tenancy issues.

We also need to update the TransactionAttribute so that it makes use of the appropriate NHibernate session:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
using Microsoft.Practices.ServiceLocation;
using SharpArchitecture.MultiTenant.Framework.Services;

namespace SharpArchitecture.MultiTenant.Framework.NHibernate
{
  public class TransactionAttribute : SharpArch.Web.NHibernate.TransactionAttribute
  {
    public TransactionAttribute()
      : base(FactoryKey)
    {
    }

    protected static string FactoryKey
    {
      get
      {
        var tenantContext = ServiceLocator.Current.GetInstance&lt;ITenantContext&gt;();
        return tenantContext.Key;
      }
    }
  }
}

Next up, we need to update the initialisation in Global.asax.cs so that we create a session factory for the master database and also for each tenant:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    private void InitializeNHibernateSession()
    {
      var mappingAssemblies = new [] { Server.MapPath("~/bin/SharpArchitecture.MultiTenant.Data.dll") };

      var configFile = Server.MapPath("~/NHibernate.config");
      NHibernateSession.Init(
            webSessionStorage,
            mappingAssemblies,
            new AutoPersistenceModelGenerator().Generate(),
            configFile);

        var tenantConfigFile = Server.MapPath("~/NHibernate.tenant.config");
        var multiTenantInitializer = ServiceLocator.Current.GetInstance&lt;IMultiTenantInitializer&gt;();
        multiTenantInitializer.Initialize(mappingAssemblies, new MultiTenantAutoPersistenceModelGenerator(),  tenantConfigFile);
    }

In the code above, the standard NHibernate.config file is used to configure the master database. Whilst NHibernate.tenant.config, along with the connection string provided by the Tenant, is used to configure the tenant databases:

1
2
3
4
5
6
7
8
9
using SharpArch.Data.NHibernate.FluentNHibernate;

namespace SharpArchitecture.MultiTenant.Framework.Services
{
  public interface IMultiTenantInitializer
  {
    void Initialize(string[] mappingAssemblies, IAutoPersistenceModelGenerator modelGenerator, string tenantConfigFile);
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
using System.Collections.Generic;
using NHibernate.Cfg;
using SharpArch.Core.PersistenceSupport;
using SharpArch.Data.NHibernate;
using SharpArch.Data.NHibernate.FluentNHibernate;
using SharpArchitecture.MultiTenant.Core;
using SharpArchitecture.MultiTenant.Framework.Services;

namespace SharpArchitecture.MultiTenant.Framework.NHibernate
{
  public class MultiTenantInitializer : IMultiTenantInitializer
  {
    private readonly IRepository&lt;Tenant&gt; _tenantRepository;

    public MultiTenantInitializer(IRepository&lt;Tenant&gt; tenantRepository)
    {
      _tenantRepository = tenantRepository;
    }

    public void Initialize(string[] mappingAssemblies, IAutoPersistenceModelGenerator modelGenerator, string tenantConfigFile)
    {
      var tenants = _tenantRepository.GetAll();
      foreach (var tenant in tenants) {
        Initialize(mappingAssemblies, modelGenerator, tenantConfigFile, tenant);
      }
    }

    private static void Initialize(string[] mappingAssemblies, IAutoPersistenceModelGenerator modelGenerator, string tenantConfigFile, Tenant tenant)
    {
      var properties = new Dictionary&lt;string, string&gt;
                         {
                           { "connection.connection_string", tenant.ConnectionString }
                         };
      AddTenantConfiguration(tenant.Domain, mappingAssemblies, modelGenerator, tenantConfigFile, properties);
    }

    private static Configuration AddTenantConfiguration(string factoryKey, string[] mappingAssemblies, IAutoPersistenceModelGenerator modelGenerator, string cfgFile, IDictionary&lt;string, string&gt; cfgProperties)
    {
      return NHibernateSession.AddConfiguration(factoryKey,
        mappingAssemblies,
        modelGenerator.Generate(),
        cfgFile,
        cfgProperties,
        null, null);
    }
  }
}

This code iterates through the list of tenants from the master database, setting the connection string and session factory key from the tenant properties and adds the configuration to NHibernate.

All that is left is to generate the mappings. In AutoPersistenceModelGenerator we move the creation of the standard mapping configuration into a method so that it can be overridden:

1
2
3
4
protected virtual IAutomappingConfiguration GetAutomappingConfiguration()
{
  return new AutomappingConfiguration();
}

And derive from AutoPersistenceModelGenerator to create our multi-tenant mapping configuration:

1
2
3
4
5
6
7
8
9
10
11
12
using FluentNHibernate.Automapping;

namespace SharpArchitecture.MultiTenant.Data.NHibernateMaps
{
  public class MultiTenantAutoPersistenceModelGenerator : AutoPersistenceModelGenerator
  {
    protected override IAutomappingConfiguration GetAutomappingConfiguration()
    {
      return new MultiTenantAutomappingConfiguration();
    }
  }
}

Then we add a method to AutomappingConfiguration to determine if a type is a multi-tenant entity (by checking to see if the type implements our IMultiTenantEntity interface):

1
2
3
4
public bool IsMultiTenantEntity(Type type)
{
  return type.GetInterfaces().Any(x =&gt; x == typeof(IMultiTenantEntity));
}

and update the ShouldMap method to only map entities that are not multi-tenant:

1
2
3
4
5
6
7
8
public override bool ShouldMap(Type type)
{
  var isMultiTenantEntity = IsMultiTenantEntity(type);
  var shouldMap = type.GetInterfaces().Any(x =&gt;
                                  x.IsGenericType &amp;&amp; x.GetGenericTypeDefinition() == typeof (IEntityWithTypedId&lt;&gt;) &amp;&amp;
                                  !isMultiTenantEntity);
  return shouldMap;
}

It is then a case of deriving from AutomappingConfiguration to map the multi-tenant entities:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
using System;

namespace SharpArchitecture.MultiTenant.Data.NHibernateMaps
{
  /// &lt;summary&gt;
  ///
  /// &lt;/summary&gt;
  public class MultiTenantAutomappingConfiguration : AutomappingConfiguration
  {
    public override bool ShouldMap(Type type)
    {
      var shouldMap = IsMultiTenantEntity(type);
      return shouldMap;
    }
  }
}

A sample application is available on GitHub.