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!
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:
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).
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.
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):
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:
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.
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:
123456789101112131415161718
namespaceSharpArch.Data.NHibernate{publicinterfaceISessionFactoryKeyProvider{/// <summary>/// Gets the session factory key./// </summary>/// <returns></returns>stringGetKey();/// <summary>/// Gets the session factory key./// </summary>/// <param name="anObject">An optional object that may have an attribute used to determine the session factory key.</param>/// <returns></returns>stringGetKeyFrom(objectanObject);}}
I’ve created a default implementation of this interface that just delegates getting the key from the existing SessionFactoryAttribute.
12345678910111213141516171819202122232425
namespaceSharpArch.Data.NHibernate{/// <summary>/// Implementation of <see cref="ISessionFactoryKeyProvider" /> that uses/// the <see cref="SessionFactoryAttribute" /> to determine the session/// factory key./// </summary>publicclassDefaultSessionFactoryKeyProvider:ISessionFactoryKeyProvider{publicstringGetKey(){returnNHibernateSession.DefaultFactoryKey;}/// <summary>/// Gets the session factory key./// </summary>/// <param name="anObject">An object that may have the <see cref="SessionFactoryAttribute"/> applied.</param>/// <returns></returns>publicstringGetKeyFrom(objectanObject){returnSessionFactoryAttribute.GetKeyFrom(anObject);}}}
I’ve also added a helper class SessionFactoryKeyHelper:
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:
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:
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.
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.
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.
1234567
namespaceSharpArchitecture.MultiTenant.Core.Contracts{/// <summary>/// Marker interface for multi tenant entities./// </summary>publicinterfaceIMultiTenantEntity{}}
We can now create our domain entities for the tenants:
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:
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:
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:
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:
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):