Optimizing nhibernate session factory, startup time of webApp really slow

后端 未结 2 1891
情书的邮戳
情书的邮戳 2021-02-02 13:33

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

2条回答
  •  不要未来只要你来
    2021-02-02 14:05

    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).

提交回复
热议问题