Using the ASP.NET compiler (via the aspnet_compiler.exe or AspNetCompiler MSBuild task) as part of your build process is a recommended approach to increase application
performace and precompile views. If you introduce NHibernate into the picture,
you may run into hard to debug exceptions during the precompilation step. For
example, when the ISessionFactory is created, it will quote any column or
table names that interfere with reserved keywords. If your database doesn’t
exist or isn’t accessible from the build server, you’re going to get a connection
exception.
It would be better if we didn’t have to query the database during the pre-compilation step (because it doesn’t actually need to!).
Solution 1
The first attempt, at least to our exception above, is to disable the column and table name quoting. There are a couple of ways to acheive this. For example, through XML configuration:
<property name="hbm2ddl.keywords">none</property>
Adversely, doing this puts us at risk of using column or table names that aren’t valid. Disabling this during debugging is OK, but our build server should be as rigid as possible.
Solution 2
The better approach is to not configure the ISessionFactory during pre-compilation.
Therefore, we need a way to detect if the application is being pre-compiled.
NOTE: This code uses implementation details and looks into the bowels of ASP.NET that could change in the future. I’ve tested it against .NET 2.0, 3.5 and 4.0 using both ASP.NET compilers. If anyone has a better approach for detecting precompilation, I’d suggest taking a look at my SO post.
public static bool IsPerformingPrecompilation()
{
var simpleApplicationHost = Assembly.GetAssembly(typeof(HostingEnvironment))
.GetType("System.Web.Hosting.SimpleApplicationHost",
throwOnError: true, ignoreCase: true);
return HostingEnvironment.InClientBuildManager &&
HostingEnvironment.ApplicationID.EndsWith("_precompile", StringComparison.InvariantCultureIgnoreCase) &&
HostingEnvironment.ApplicationHost.GetType() == simpleApplicationHost;
}
Now, we can easily disable creation of the ISessionFactory if the application
is being precompiled. You could, for example, put this code inside of your IoC container’s
setup:
if (IsPerformingPreCompilation())
{
return;
}
// Configuration creation snipped...
var sessionFactoy = configuration.BuildSessionFactory();
// Wire up sessionFactory with your IoC container etc.
Conclusion
NHibernate shouldn’t have to hit the database when using the ASP.NET compiler. The
simplest fix is to ignore creation of the ISessionFactory all together. Although
this approach might be a bit adventurous, I’ve been using it for a couple of
applications without any issues.

