I have implement testing app. which uses fluent nhibernate mapping to db object inside mssql db. Since I want to learn fine tune nhib. mvc3 applications, I\'m using this app. fo
You can improve the startup time (of both web and windows applications) by caching the Configurations. The following class will do this job:
using System.IO;
using System.Reflection;
using System.Runtime.Serialization.Formatters.Binary;
using System.Web;
using NHibernate.Cfg;
namespace NH32AutoMap.Core
{
public class ConfigurationFileCache
{
private readonly string _cacheFile;
private readonly Assembly _definitionsAssembly;
public ConfigurationFileCache(Assembly definitionsAssembly)
{
_definitionsAssembly = definitionsAssembly;
_cacheFile = "nh.cfg";
if (HttpContext.Current != null) //for the web apps
_cacheFile = HttpContext.Current.Server.MapPath(
string.Format("~/App_Data/{0}", _cacheFile)
);
}
public void DeleteCacheFile()
{
if (File.Exists(_cacheFile))
File.Delete(_cacheFile);
}
public bool IsConfigurationFileValid
{
get
{
if (!File.Exists(_cacheFile))
return false;
var configInfo = new FileInfo(_cacheFile);
var asmInfo = new FileInfo(_definitionsAssembly.Location);
if (configInfo.Length < 5 * 1024)
return false;
return configInfo.LastWriteTime >= asmInfo.LastWriteTime;
}
}
public void SaveConfigurationToFile(Configuration configuration)
{
using (var file = File.Open(_cacheFile, FileMode.Create))
{
var bf = new BinaryFormatter();
bf.Serialize(file, configuration);
}
}
public Configuration LoadConfigurationFromFile()
{
if (!IsConfigurationFileValid)
return null;
using (var file = File.Open(_cacheFile, FileMode.Open, FileAccess.Read))
{
var bf = new BinaryFormatter();
return bf.Deserialize(file) as Configuration;
}
}
}
}
To use that,
private Configuration readConfigFromCacheFileOrBuildIt()
{
Configuration nhConfigurationCache;
var nhCfgCache = new ConfigurationFileCache(MappingsAssembly);
var cachedCfg = nhCfgCache.LoadConfigurationFromFile();
if (cachedCfg == null)
{
nhConfigurationCache = buildConfiguration();
nhCfgCache.SaveConfigurationToFile(nhConfigurationCache);
}
else
{
nhConfigurationCache = cachedCfg;
}
return nhConfigurationCache;
}
And then before calling the BuildSessionFactory, we can read the config file from cache or if the mappings have changed, build it and cache it again:
public ISessionFactory SetUpSessionFactory()
{
var config = readConfigFromCacheFileOrBuildIt();
var sessionFactory = config.BuildSessionFactory();
Here you can find a full sample: (^). + If you want to make it work, separate domain classes and mappings definitions assemblies from the main application's assembly (because the ConfigurationFileCache class will delete the cache file if the mappings definitions assembly is newer than the cache file's LastWriteTime).
IIRC correctly, it is not a good idea to create objects in the contructor of HttpApplication (or its subclasses such as MvcApplication). Better to create the session factory in the Application_Start handler.
You should remove NHibernate profiler (since all profilers might affect the measurements). Instead, put the call to CreateSessionFactory() and surround it with use of the Stopwatch class to get an accurate measurement.
Is your database server slow to respond? Because of connection pooling this might only be noticeable on the first occasion.
NHibernate do take some time to initialize, but 4 seconds with one lightweight entity do seem too much. This is of course affected by the general performance of the test system though.