.NET Core 6配置NHibernate二级缓存时遇CacheFactory为空错误
解决ASP.NET Core 6中NHibernate CoreDistributedCacheProvider的配置问题
错误原因
报错InvalidOperationException: CacheFactory is null...是因为CoreDistributedCacheProvider必须指定缓存工厂实现,原Web.Config中通过factory-class属性指定了内存缓存工厂,但迁移到Core后没有对应配置,导致NHibernate无法找到缓存工厂。
解决方案
提供两种可行方案,选一种即可:
方案1:将原XML配置迁移到appsettings.json
- 在
appsettings.json中添加对应配置节点,和原Web.Config结构匹配:
{ "coredistributedcache": { "factory-class": "NHibernate.Caches.CoreDistributedCache.Memory.MemoryFactory, NHibernate.Caches.CoreDistributedCache.Memory", "properties": { "expiration-scan-frequency": "00:10:00", "size-limit": "1048576", "cache.serializer": "NHibernate.Caches.Util.JsonSerializer.JsonCacheSerializer, NHibernate.Caches.Util.JsonSerializer" }, "caches": [ { "region": "foo", "expiration": "500", "sliding": "true" }, { "region": "noExplicitExpiration", "sliding": "true" }, { "region": "specificSerializer", "serializer": "NHibernate.Caches.Common.BinaryCacheSerializer, NHibernate.Caches.Common" } ] } }
- 修改Fluent NHibernate配置代码,读取并绑定配置:
ASP.NET Core 6中IConfiguration已默认注册,直接在构造函数注入即可:
private readonly IConfiguration _configuration; public YourSessionFactoryBuilder(IConfiguration configuration) { _configuration = configuration; } public ISessionFactory BuildSessionFactory() { // 读取appsettings中的缓存配置 var cacheConfigSection = _configuration.GetSection("coredistributedcache"); var sectionHandler = new CoreDistributedCacheSectionHandler(); var cacheConfig = sectionHandler.Create(null, null, cacheConfigSection.GetRawJson()); // 将配置传递给NHibernate缓存提供程序 CoreDistributedCacheProvider.SetConfiguration(cacheConfig); var fluentConfiguration = Fluently.Configure() .Database(PostgreSQLConfiguration.Standard.Dialect<MySQL5Dialect>() .ConnectionString(x => x.Host("**") .Port(5432) .Database("**") .Username("**") .Password("**"))) .Mappings(m => m.FluentMappings.AddFromAssembly(assembly).Conventions.Add(new DatabaseConvention())) .Cache(o => o.UseSecondLevelCache().UseQueryCache().ProviderClass<CoreDistributedCacheProvider>()); return fluentConfiguration.BuildSessionFactory(); }
方案2:纯编程式配置(无需配置文件)
直接在代码中指定缓存工厂和配置,更直观:
public ISessionFactory BuildSessionFactory() { // 初始化内存缓存工厂 var cacheFactory = new MemoryFactory(); cacheFactory.Initialize(new Dictionary<string, string> { {"expiration-scan-frequency", "00:10:00"}, {"size-limit", "1048576"}, {"cache.serializer", "NHibernate.Caches.Util.JsonSerializer.JsonCacheSerializer, NHibernate.Caches.Util.JsonSerializer"} }); // 设置缓存工厂到提供程序 CoreDistributedCacheProvider.SetCacheFactory(cacheFactory); // 配置特定缓存区域(可选) CoreDistributedCacheProvider.SetRegionProperties("foo", new Dictionary<string, string> { {"expiration", "500"}, {"sliding", "true"} }); var fluentConfiguration = Fluently.Configure() .Database(PostgreSQLConfiguration.Standard.Dialect<MySQL5Dialect>() .ConnectionString(x => x.Host("**") .Port(5432) .Database("**") .Username("**") .Password("**"))) .Mappings(m => m.FluentMappings.AddFromAssembly(assembly).Conventions.Add(new DatabaseConvention())) .Cache(o => o.UseSecondLevelCache().UseQueryCache().ProviderClass<CoreDistributedCacheProvider>()); return fluentConfiguration.BuildSessionFactory(); }
注意事项
- 确保已安装对应NuGet包:
NHibernate.Caches.CoreDistributedCache、NHibernate.Caches.CoreDistributedCache.Memory、NHibernate.Caches.Util.JsonSerializer。 - 原代码中
PostgreSQLConfiguration搭配MySQL5Dialect是笔误,建议改为PostgreSQLDialect避免潜在问题。
内容的提问来源于stack exchange,提问作者tsiro
相关产品推荐
相关产品推荐

