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 collectionMetadata; [NonSerialized] - private readonly Dictionary collectionPersisters; + private readonly IReadOnlyDictionary collectionPersisters; [NonSerialized] private readonly ILookup collectionPersistersSpaces; [NonSerialized] - private readonly IDictionary> collectionRolesByEntityParticipant; + private readonly IReadOnlyDictionary> collectionRolesByEntityParticipant; [NonSerialized] private readonly ICurrentSessionContext currentSessionContext; [NonSerialized] private readonly IEntityNotFoundDelegate entityNotFoundDelegate; [NonSerialized] - private readonly IDictionary entityPersisters; + private readonly IReadOnlyDictionary entityPersisters; [NonSerialized] private readonly ILookup entityPersistersSpaces; @@ -130,7 +130,7 @@ public void HandleEntityNotFound(string entityName, string propertyName, object /// /// this is a shortcut. [NonSerialized] - private readonly IDictionary implementorToEntityName; + private readonly IReadOnlyDictionary implementorToEntityName; [NonSerialized] private readonly EventListeners eventListeners; @@ -138,19 +138,19 @@ public void HandleEntityNotFound(string entityName, string propertyName, object [NonSerialized] private readonly Dictionary filters; [NonSerialized] - private readonly Dictionary identifierGenerators; + private readonly IReadOnlyDictionary identifierGenerators; [NonSerialized] - private readonly Dictionary imports; + private readonly IReadOnlyDictionary imports; [NonSerialized] private readonly IInterceptor interceptor; private readonly string name; [NonSerialized] - private readonly Dictionary namedQueries; + private readonly IReadOnlyDictionary namedQueries; [NonSerialized] - private readonly Dictionary namedSqlQueries; + private readonly IReadOnlyDictionary namedSqlQueries; [NonSerialized] private readonly IDictionary properties; @@ -168,7 +168,7 @@ public void HandleEntityNotFound(string entityName, string propertyName, object [NonSerialized] private readonly SQLFunctionRegistry sqlFunctionRegistry; [NonSerialized] - private readonly Dictionary sqlResultSetMappings; + private readonly ReadOnlyDictionary 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(); + var tmpIdentifierGenerators = new Dictionary(); 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(tmpIdentifierGenerators); #endregion #region Persisters var caches = new Dictionary, ICacheConcurrencyStrategy>(); - entityPersisters = new Dictionary(); - implementorToEntityName = new Dictionary(); + var tmpEntityPersisters = new Dictionary(); + var tmpImplementorToEntityName = new Dictionary(); Dictionary classMeta = new Dictionary(); @@ -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(tmpEntityPersisters); + implementorToEntityName = new ReadOnlyDictionary(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(classMeta); Dictionary> tmpEntityToCollectionRoleMap = new Dictionary>(); - collectionPersisters = new Dictionary(); + var tmpCollectionPersisters = new Dictionary(); 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(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(cfg.NamedQueries); - namedSqlQueries = new Dictionary(cfg.NamedSQLQueries); - sqlResultSetMappings = new Dictionary(cfg.SqlResultSetMappings); + namedQueries = new ReadOnlyDictionary(cfg.NamedQueries); + namedSqlQueries = new ReadOnlyDictionary(cfg.NamedSQLQueries); + sqlResultSetMappings = new ReadOnlyDictionary(cfg.SqlResultSetMappings); #endregion - imports = new Dictionary(cfg.Imports); + imports = new ReadOnlyDictionary(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 Instances = new Dictionary(); - private static readonly IDictionary NamedInstances = new Dictionary(); + private static readonly IDictionary Instances = new ConcurrentDictionary(); + private static readonly IDictionary NamedInstances = new ConcurrentDictionary(); /// static SessionFactoryObjectFactory()