diff --git a/src/NHibernate/Impl/SessionFactoryImpl.cs b/src/NHibernate/Impl/SessionFactoryImpl.cs
index 8ff1e9d1599..1e89533b641 100644
--- a/src/NHibernate/Impl/SessionFactoryImpl.cs
+++ b/src/NHibernate/Impl/SessionFactoryImpl.cs
@@ -110,18 +110,18 @@ public void HandleEntityNotFound(string entityName, string propertyName, object
 		[NonSerialized]
 		private readonly IDictionary<string, ICollectionMetadata> collectionMetadata;
 		[NonSerialized]
-		private readonly Dictionary<string, ICollectionPersister> collectionPersisters;
+		private readonly IReadOnlyDictionary<string, ICollectionPersister> collectionPersisters;
 		[NonSerialized]
 		private readonly ILookup<string, ICollectionPersister> collectionPersistersSpaces;
 
 		[NonSerialized]
-		private readonly IDictionary<string, ISet<string>> collectionRolesByEntityParticipant;
+		private readonly IReadOnlyDictionary<string, ISet<string>> collectionRolesByEntityParticipant;
 		[NonSerialized]
 		private readonly ICurrentSessionContext currentSessionContext;
 		[NonSerialized]
 		private readonly IEntityNotFoundDelegate entityNotFoundDelegate;
 		[NonSerialized]
-		private readonly IDictionary<string, IEntityPersister> entityPersisters;
+		private readonly IReadOnlyDictionary<string, IEntityPersister> entityPersisters;
 		[NonSerialized]
 		private readonly ILookup<string, IEntityPersister> entityPersistersSpaces;
 
@@ -130,7 +130,7 @@ public void HandleEntityNotFound(string entityName, string propertyName, object
 		/// </summary>
 		/// <remarks>this is a shortcut.</remarks>
 		[NonSerialized]
-		private readonly IDictionary<System.Type, string> implementorToEntityName;
+		private readonly IReadOnlyDictionary<System.Type, string> implementorToEntityName;
 
 		[NonSerialized]
 		private readonly EventListeners eventListeners;
@@ -138,19 +138,19 @@ public void HandleEntityNotFound(string entityName, string propertyName, object
 		[NonSerialized]
 		private readonly Dictionary<string, FilterDefinition> filters;
 		[NonSerialized]
-		private readonly Dictionary<string, IIdentifierGenerator> identifierGenerators;
+		private readonly IReadOnlyDictionary<string, IIdentifierGenerator> identifierGenerators;
 
 		[NonSerialized]
-		private readonly Dictionary<string, string> imports;
+		private readonly IReadOnlyDictionary<string, string> imports;
 
 		[NonSerialized]
 		private readonly IInterceptor interceptor;
 		private readonly string name;
 		[NonSerialized]
-		private readonly Dictionary<string, NamedQueryDefinition> namedQueries;
+		private readonly IReadOnlyDictionary<string, NamedQueryDefinition> namedQueries;
 
 		[NonSerialized]
-		private readonly Dictionary<string, NamedSQLQueryDefinition> namedSqlQueries;
+		private readonly IReadOnlyDictionary<string, NamedSQLQueryDefinition> namedSqlQueries;
 
 		[NonSerialized]
 		private readonly IDictionary<string, string> properties;
@@ -168,7 +168,7 @@ public void HandleEntityNotFound(string entityName, string propertyName, object
 		[NonSerialized]
 		private readonly SQLFunctionRegistry sqlFunctionRegistry;
 		[NonSerialized]
-		private readonly Dictionary<string, ResultSetMappingDefinition> sqlResultSetMappings;
+		private readonly ReadOnlyDictionary<string, ResultSetMappingDefinition> sqlResultSetMappings;
 		[NonSerialized]
 		private readonly UpdateTimestampsCache updateTimestampsCache;
 		[NonSerialized]
@@ -248,7 +248,7 @@ public SessionFactoryImpl(Configuration cfg, IMapping mapping, Settings settings
 			#endregion
 
 			#region Generators
-			identifierGenerators = new Dictionary<string, IIdentifierGenerator>();
+			var tmpIdentifierGenerators = new Dictionary<string, IIdentifierGenerator>();
 			foreach (PersistentClass model in cfg.ClassMappings)
 			{
 				if (!model.IsInherited)
@@ -257,16 +257,17 @@ public SessionFactoryImpl(Configuration cfg, IMapping mapping, Settings settings
 						model.Identifier.CreateIdentifierGenerator(settings.Dialect, settings.DefaultCatalogName,
 																   settings.DefaultSchemaName, (RootClass)model);
 
-					identifierGenerators[model.EntityName] = generator;
+					tmpIdentifierGenerators[model.EntityName] = generator;
 				}
 			}
+			identifierGenerators = new ReadOnlyDictionary<string, IIdentifierGenerator>(tmpIdentifierGenerators);
 			#endregion
 
 			#region Persisters
 
 			var caches = new Dictionary<Tuple<string, string>, ICacheConcurrencyStrategy>();
-			entityPersisters = new Dictionary<string, IEntityPersister>();
-			implementorToEntityName = new Dictionary<System.Type, string>();
+			var tmpEntityPersisters = new Dictionary<string, IEntityPersister>();
+			var tmpImplementorToEntityName = new Dictionary<System.Type, string>();
 
 			Dictionary<string, IClassMetadata> classMeta = new Dictionary<string, IClassMetadata>();
 
@@ -280,15 +281,18 @@ public SessionFactoryImpl(Configuration cfg, IMapping mapping, Settings settings
 					model.EntityName,
 					caches);
 				var cp = PersisterFactory.CreateClassPersister(model, cache, this, mapping);
-				entityPersisters[model.EntityName] = cp;
+				tmpEntityPersisters[model.EntityName] = cp;
 				classMeta[model.EntityName] = cp.ClassMetadata;
 
 				if (model.HasPocoRepresentation)
 				{
-					implementorToEntityName[model.MappedClass] = model.EntityName;
+					tmpImplementorToEntityName[model.MappedClass] = model.EntityName;
 				}
 			}
 
+			entityPersisters = new ReadOnlyDictionary<string, IEntityPersister>(tmpEntityPersisters);
+			implementorToEntityName = new ReadOnlyDictionary<System.Type, string>(tmpImplementorToEntityName);
+
 			entityPersistersSpaces = entityPersisters
 				.SelectMany(x => x.Value.QuerySpaces.Select(y => new { QuerySpace = y, Persister = x.Value }))
 				.ToLookup(x => x.QuerySpace, x => x.Persister);
@@ -296,7 +300,7 @@ public SessionFactoryImpl(Configuration cfg, IMapping mapping, Settings settings
 			classMetadata = new ReadOnlyDictionary<string, IClassMetadata>(classMeta);
 
 			Dictionary<string, ISet<string>> tmpEntityToCollectionRoleMap = new Dictionary<string, ISet<string>>();
-			collectionPersisters = new Dictionary<string, ICollectionPersister>();
+			var tmpCollectionPersisters = new Dictionary<string, ICollectionPersister>();
 			foreach (Mapping.Collection model in cfg.CollectionMappings)
 			{
 				var cache = GetCacheConcurrencyStrategy(
@@ -306,7 +310,7 @@ public SessionFactoryImpl(Configuration cfg, IMapping mapping, Settings settings
 					model.OwnerEntityName,
 					caches);
 				var persister = PersisterFactory.CreateCollectionPersister(model, cache, this);
-				collectionPersisters[model.Role] = persister;
+				tmpCollectionPersisters[model.Role] = persister;
 				IType indexType = persister.IndexType;
 				if (indexType != null && indexType.IsAssociationType && !indexType.IsAnyType)
 				{
@@ -333,6 +337,8 @@ public SessionFactoryImpl(Configuration cfg, IMapping mapping, Settings settings
 				}
 			}
 
+			collectionPersisters = new ReadOnlyDictionary<string, ICollectionPersister>(tmpCollectionPersisters);
+
 			collectionPersistersSpaces = collectionPersisters
 				.SelectMany(x => x.Value.CollectionSpaces.Select(y => new { QuerySpace = y, Persister = x.Value }))
 				.ToLookup(x => x.QuerySpace, x => x.Persister);
@@ -347,12 +353,12 @@ public SessionFactoryImpl(Configuration cfg, IMapping mapping, Settings settings
 			#endregion
 
 			#region Named Queries
-			namedQueries = new Dictionary<string, NamedQueryDefinition>(cfg.NamedQueries);
-			namedSqlQueries = new Dictionary<string, NamedSQLQueryDefinition>(cfg.NamedSQLQueries);
-			sqlResultSetMappings = new Dictionary<string, ResultSetMappingDefinition>(cfg.SqlResultSetMappings);
+			namedQueries = new ReadOnlyDictionary<string, NamedQueryDefinition>(cfg.NamedQueries);
+			namedSqlQueries = new ReadOnlyDictionary<string, NamedSQLQueryDefinition>(cfg.NamedSQLQueries);
+			sqlResultSetMappings = new ReadOnlyDictionary<string, ResultSetMappingDefinition>(cfg.SqlResultSetMappings);
 			#endregion
 
-			imports = new Dictionary<string, string>(cfg.Imports);
+			imports = new ReadOnlyDictionary<string, string>(cfg.Imports);
 
 			#region after *all* persisters and named queries are registered
 			foreach (IEntityPersister persister in entityPersisters.Values)
diff --git a/src/NHibernate/Impl/SessionFactoryObjectFactory.cs b/src/NHibernate/Impl/SessionFactoryObjectFactory.cs
index 2936f5c2405..190bcb4b525 100644
--- a/src/NHibernate/Impl/SessionFactoryObjectFactory.cs
+++ b/src/NHibernate/Impl/SessionFactoryObjectFactory.cs
@@ -1,3 +1,4 @@
+using System.Collections.Concurrent;
 using System.Collections.Generic;
 using System.Runtime.CompilerServices;
 
@@ -21,8 +22,8 @@ public static class SessionFactoryObjectFactory
 	{
 		private static readonly INHibernateLogger log;
 
-		private static readonly IDictionary<string, ISessionFactory> Instances = new Dictionary<string, ISessionFactory>();
-		private static readonly IDictionary<string, ISessionFactory> NamedInstances = new Dictionary<string, ISessionFactory>();
+		private static readonly IDictionary<string, ISessionFactory> Instances = new ConcurrentDictionary<string, ISessionFactory>();
+		private static readonly IDictionary<string, ISessionFactory> NamedInstances = new ConcurrentDictionary<string, ISessionFactory>();
 
 		/// <summary></summary>
 		static SessionFactoryObjectFactory()