Monday, May 6, 2013

Entity Framework 5 Code First Multi-Tenancy with Migrations

The Entity Framework 5 Code First Migrations mechanism works great, however there is a small issue regarding multi tenant applications where the same DbContext is used to connect to multiple databases with the same schema.

To be able to address multiple databases with the same schema, you could have two constructors:

public class MyDbContext : DbContext
{
   public MyDbContext() : 
      base( defaultconnectionstring )
   {
   }
 
   public MyDbContext( string ConnectionString ) : 
      base( ConnectionString )
   {
   }
}

or have a single, parameterless constructor but set the connection string after a context has been created. In both cases, the default parameterless constructor will always somehow point to a concrete, default database.

This raises following problem - the MigrateDatabaseToLatestVersion initializer creates your context using the default parameterless dbcontext constructor. It will migrate the database but only the default one! It seems that people report this issue.

To fix this, we need a modified database initializer. The initializer should migrate the current database rather than the default one. It means that the initializer should get the connection string from the current context somehow. Luckily, this is possible:

// an example code first data context
public class MasterDetailContext : DbContext
{
    public DbSet<Detail> Detail { get; set; }
    public DbSet<Master> Master { get; set; }
 
    // this one is used by DbMigrator but the client code will not use it
    public MasterDetailContext()
    {
        Database.Initialize( false );
    }
 
    // rather - the client code will use this one
    public MasterDetailContext( string ConnectionString ) : base( ConnectionString )
    {
        Database.SetInitializer( new CustomInitializer() );
        Database.Initialize( false );
    }
 
    protected override void  OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
    }
}
 
public class CustomInitializer : 
   IDatabaseInitializer<MasterDetailContext>
{
 
    #region IDatabaseInitializer<MasterDetailContext> Members
 
    // fix the problem with MigrateDatabaseToLatestVersion 
    // by copying the connection string FROM the actual context!
    public void InitializeDatabase( MasterDetailContext context )
    {            
        Configuration cfg = new Configuration(); // migration configuration class
        cfg.TargetDatabase = 
           new DbConnectionInfo( 
              context.Database.Connection.ConnectionString, 
              "System.Data.SqlClient" );
 
        DbMigrator dbMigrator = new DbMigrator( cfg );
        // this will call the parameterless constructor of the datacontext
        // but the connection string from above will be then set on in
        dbMigrator.Update();             
    }
 
    #endregion
}

The client code is now:

// Connect to two different schemas using the same context
// Use sql profier to see how both databases are migrated
using ( MasterDetailContext ctx = 
   new MasterDetailContext( @"Database=Database01;Server=.\SQL2012;Integrated Security=true" ) )
{
}
 
using ( MasterDetailContext ctx = 
   new MasterDetailContext( @"Database=Database02;Server=.\SQL2012;Integrated Security=true" ) )
{
}

Compare our new custom initializer with the existing MigrateDatabaseToLatestVersion initializer:

// The builtin initializer class
public class MigrateDatabaseToLatestVersion<TContext, TMigrationsConfiguration> : 
   IDatabaseInitializer<TContext> 
      where TContext : DbContext 
      where TMigrationsConfiguration : DbMigrationsConfiguration<TContext>, new()
{
   private readonly DbMigrationsConfiguration _config;
 
   public MigrateDatabaseToLatestVersion()
   {
      // creates the migrations configuration instance
      this._config = Activator.CreateInstance<TMigrationsConfiguration>();
   }
 
   public void InitializeDatabase(TContext context)
   {
      // migrates the default database (doesn't use context!)
      DbMigrator dbMigrator = new DbMigrator(this._config);
      dbMigrator.Update();
   }   
}

Differences are obvious.

The built in initializer uses reflection to create the instance of the migrations configurator and asks DbMigrator to perform the update but it doesn’t ask it for the connection to the current database! Instead, the configurator by itself creates a new instance of the DbContext using the default parameterless constructor. On the other hand, our custom initializer uses the information on the context to set the configurator’s TargetDatabase to point to a current database.

This way, multiple databases can be migrated independently.

Wednesday, March 27, 2013

Annotation-based Documentation Provider for APIExplorer

The APIExplorer is a nice way to automatically build a docs page for your WebAPI RESTful services. The documentation is created using reflection and then the IDocumentationProvider tries to find the textual information about your methods and method parameters.

The problem is that the reference implementation shows how the docs could be retrieved from the XML documentation generated during the compilation of a service. If this is not an option for you, you could use this simple provider which uses System.ComponentModel.DataAnnotations.Display attributes for method decoration:

public class AttributeDocumentationProvider : IDocumentationProvider
 {
     #region IDocumentationProvider Members
 
     public string GetDocumentation( HttpParameterDescriptor parameterDescriptor )
     {
         ReflectedHttpParameterDescriptor reflectedParameterDescriptor = 
             parameterDescriptor as ReflectedHttpParameterDescriptor;
         if ( reflectedParameterDescriptor != null )
         {
             var display = reflectedParameterDescriptor.ParameterInfo
                 .GetCustomAttributes( typeof( DisplayAttribute ), false )
                 .OfType<DisplayAttribute>().FirstOrDefault();
             if ( display != null )
                 return display.Description;
             else
                 return reflectedParameterDescriptor.ParameterInfo.Name;
         }
 
         return string.Empty;
     }
 
     public string GetDocumentation( HttpActionDescriptor actionDescriptor )
     {
         ReflectedHttpActionDescriptor reflectedActionDescriptor = 
             actionDescriptor as ReflectedHttpActionDescriptor;
         if ( reflectedActionDescriptor != null )
         {
             var display = reflectedActionDescriptor.MethodInfo
                 .GetCustomAttributes( typeof( DisplayAttribute ), false )
                 .OfType<DisplayAttribute>().FirstOrDefault();
             if ( display != null )
                 return display.Description;
             else
                 return reflectedActionDescriptor.MethodInfo.Name;
         }
 
         return string.Empty;
     }
 
     #endregion
 }

This way the WebAPI controller could be documented as follows:

public class MyWebAPIController : ApiController
{
    /// <summary>
    /// POST/Create a new Foo
    /// </summary>
    [Display( Description="Create a new instance of Foo")]
    public HttpResponseMessage PostFoo( 
        [Display( Description="Name of the newly created Foo")]
        string fooName 
        )
    {
       ...

An advantage of this approach is that the docs are part of the assembly metadata and there is no need for external XML documentation files.

Wednesday, March 20, 2013

Unity and Http Per Request Lifetime Manager

A common requirement for an IoC container is to support different lifetime managers with at least the “transient” and “container controlled” provided out-of-the-box. Unity is no exception and lifetime management works great.

Another, more specific but still common requirement is to have a “per-request” lifetime manager so that the container would resolve the same the instance of your service in a http request scope but different scopes would yield different instances of the service. This way for example, the container could serve database sessions with no risk of unintented concurrency issues.

The small inconvenience of Unity is that the “per request” manager is not provided and you have to bake one on your own. The aim of this post is to warn the reader that although this sounds like an easy task, one can easily find an incorrent implementation and get into trouble.

Let us take these two implementations and compare them:

  1. Using Microsoft Unity in ASP.NET MVC by Brian Mains
  2. Unity and lifetime management by John Bledsoe

First one:

public class HttpContextLifetimeManager<T> : LifetimeManager, IDisposable
{
    private HttpContextBase _context = null;
    public HttpContextLifetimeManager()
    {
        _context = new HttpContextWrapper(HttpContext.Current);
    }
    public HttpContextLifetimeManager(HttpContextBase context)
    {
        if (context == null)
            throw new ArgumentNullException("context");
        _context = context;
    }
    public void Dispose()
    {
        this.RemoveValue();
    }
    public override object GetValue()
    {
        return _context.Items[typeof(T)];
    }
    public override void RemoveValue()
    {
        _context.Items.Remove(typeof(T));
    }
    public override void SetValue(object newValue)
    {
        _context.Items[typeof(T)] = newValue;
    }
}

The second one:

public class PerRequestLifetimeManager : LifetimeManager
{
    private readonly object key = new object();
 
    public override object GetValue()
    {
        if (HttpContext.Current != null && 
            HttpContext.Current.Items.Contains(key))
            return HttpContext.Current.Items[key];
        else
            return null;
    }
 
    public override void RemoveValue()
    {
        if (HttpContext.Current != null)
            HttpContext.Current.Items.Remove(key);
    }
 
    public override void SetValue(object newValue)
    {
        if (HttpContext.Current != null)
            HttpContext.Current.Items[key] = newValue;
    }
}

Seemingly both are correct as both use the Items container which is request-specific which means that items are stored to and retrieved from the request specific context. So far, so good.

However, there is a fundamental problem in the first implementation. The problem comes from the fact that the lifetime manager has its own lifetime management policy – the manager is created once for a container and registered type.

In a web application, typically you have a single, shared container in the http application scope. Following the Composition Root principle, you initialize the container and your services somewhere early in the application’s life cycle but the container is alive and is reused when there is a need to resolve services in the application scope.

In the first approach, the lifetime manager is initialized once and it always uses the http context of the very first request, storing the context in a private variable and reusing it in subsequent requests. This, of course, is completely against the requirement to always use the current request context!

Lesson learned – pay a close attention to the lifetime management policy and how it is implemented.