Reducing application startup time

The process of configuring NHibernate is fairly intensive and takes some time. NHibernate has to load, parse, and compile all our mappings and reflect the model. In this recipe, I'll show you how to reduce the startup time of your NHibernate application.

Getting ready

Complete the Configuring NHibernate with App.config recipe from the beginning of this chapter.

How to do it...

  1. Add a reference to System.Configuration.dll.
  2. Add a new class named ConfigurationBuilder.
  3. Add the following using statements:
    using System;
    using System.Configuration;
    using System.IO;
    using System.Reflection;
    using System.Runtime.Serialization.Formatters.Binary;
    using Configuration = NHibernate.Cfg.Configuration;
  4. In ConfigurationBuilder, add a private string constant SERIALIZED_CFG = "configuration.bin";
  5. Add a method named Build with the following code:
    public Configuration Build()
    {
      Configuration cfg = LoadConfigurationFromFile();
      if (cfg == null)
      {
        cfg = new Configuration().Configure();
        SaveConfigurationToFile(cfg);
      }
      return cfg;
    }
  6. Add a method named LoadConfigurationFromFile with this code:
    private Configuration LoadConfigurationFromFile()
    {
      if (!IsConfigurationFileValid())
        return null;
      try
      {
        using (var file = File.Open(SERIALIZED_CFG, FileMode.Open))
        {
          var bf = new BinaryFormatter();
          return bf.Deserialize(file) as Configuration;
        }
      }
      catch (Exception)
      {
        // Something went wrong
        // Just build a new one
        return null;
      }
    }
  7. Add a method named IsConfigurationFileValid with the following code:
    private bool IsConfigurationFileValid()
    {
      // If we don't have a cached config, 
      // force a new one to be built
      if (!File.Exists(SERIALIZED_CFG))
        return false;
      var configInfo = new FileInfo(SERIALIZED_CFG);
      var asm = Assembly.GetExecutingAssembly();
      if (asm.Location == null)
        return false;
      // If the assembly is newer, 
      // the serialized config is stale
      var asmInfo = new FileInfo(asm.Location);
      if (asmInfo.LastWriteTime > configInfo.LastWriteTime)
        return false;
      // If the app.config is newer, 
      // the serialized config is stale
      var appDomain = AppDomain.CurrentDomain;
      var appConfigPath = appDomain.SetupInformation.ConfigurationFile;
      var appConfigInfo = new FileInfo(appConfigPath);
      if (appConfigInfo.LastWriteTime > configInfo.LastWriteTime)
        return false;
      // It's still fresh
      return true;
    }
  8. Add a method named SaveConfigurationToFile with this code:
    private void SaveConfigurationToFile(Configuration cfg)
    {
      using (var file = File.Open(SERIALIZED_CFG, FileMode.Create))
      {
        var bf = new BinaryFormatter();
        bf.Serialize(file, cfg);
      }
    }
  9. In Program.cs, replace the NHibernate configuration code with the following code:
    var nhConfig = new ConfigurationBuilder().Build();

How it works...

NHibernate's Configuration class is serializable. Thoroughly validating the mappings and settings takes some effort and time. The very first time our application runs, we can't escape this, but if we serialize our Configuration object to disk, we can deserialize it the next time we run it, saving us all of this busy work.

The IsConfigurationFileValid method ensures that the Configuration we've serialized is still fresh. If the executable or the App.config has been updated, we need to rebuild our configuration object from scratch.

We compare the last write time of the various files to decide if the serialized configuration is stale. We use a BinaryFormatter to serialize and deserialize the configuration.

Tip

Actual configuration may vary—batteries not included

In this recipe, we only check the assembly containing our ConfigurationBuilder class and the App.config. If you store your configuration and mappings elsewhere, you will need to adjust this code accordingly.

There's more...

This technique is especially suited for development and test suites, where we frequently change code, but may not change our mappings or configuration. We can skip all of the extra parsing and get running quickly, and test our changes.

It also works well for desktop NHibernate applications. Because a user is waiting on your application to launch, every second counts. It's not as useful for web applications in production because these basically launch once and stay running.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.141.27.74