|
From: <fab...@us...> - 2011-05-08 22:59:25
|
Revision: 5800
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5800&view=rev
Author: fabiomaulo
Date: 2011-05-08 22:59:17 +0000 (Sun, 08 May 2011)
Log Message:
-----------
Fixed class registration ambiguity resolution
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Mapping/ByCode/ExplicitlyDeclaredModel.cs
trunk/nhibernate/src/NHibernate/Mapping/ByCode/SimpleModelInspector.cs
trunk/nhibernate/src/NHibernate/NHibernate.csproj
trunk/nhibernate/src/NHibernate.Test/MappingByCode/ExplicitlyDeclaredModelTests/ComponentMappingRegistrationTests.cs
trunk/nhibernate/src/NHibernate.Test/MappingByCode/ExplicitlyDeclaredModelTests/JoinedSubclassMappingStrategyTests.cs
trunk/nhibernate/src/NHibernate.Test/MappingByCode/ExplicitlyDeclaredModelTests/RootClassMappingStrategyTests.cs
trunk/nhibernate/src/NHibernate.Test/MappingByCode/ExplicitlyDeclaredModelTests/SubclassMappingStrategyTests.cs
trunk/nhibernate/src/NHibernate.Test/MappingByCode/ExplicitlyDeclaredModelTests/UnionSubclassMappingStrategyTests.cs
trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj
Added Paths:
-----------
trunk/nhibernate/src/NHibernate/Mapping/ByCode/AbstractExplicitlyDeclaredModel.cs
trunk/nhibernate/src/NHibernate.Test/MappingByCode/MixAutomapping/CallCustomConditions.cs
Added: trunk/nhibernate/src/NHibernate/Mapping/ByCode/AbstractExplicitlyDeclaredModel.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Mapping/ByCode/AbstractExplicitlyDeclaredModel.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/AbstractExplicitlyDeclaredModel.cs 2011-05-08 22:59:17 UTC (rev 5800)
@@ -0,0 +1,571 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+
+namespace NHibernate.Mapping.ByCode
+{
+ public abstract class AbstractExplicitlyDeclaredModel : IModelExplicitDeclarationsHolder
+ {
+ private readonly HashSet<MemberInfo> any = new HashSet<MemberInfo>();
+ private readonly HashSet<MemberInfo> arrays = new HashSet<MemberInfo>();
+ private readonly HashSet<MemberInfo> bags = new HashSet<MemberInfo>();
+ private readonly HashSet<System.Type> components = new HashSet<System.Type>();
+ private readonly HashSet<MemberInfo> dictionaries = new HashSet<MemberInfo>();
+ private readonly HashSet<MemberInfo> idBags = new HashSet<MemberInfo>();
+ private readonly HashSet<MemberInfo> lists = new HashSet<MemberInfo>();
+ private readonly HashSet<MemberInfo> manyToManyRelations = new HashSet<MemberInfo>();
+ private readonly HashSet<MemberInfo> manyToOneRelations = new HashSet<MemberInfo>();
+ private readonly HashSet<MemberInfo> naturalIds = new HashSet<MemberInfo>();
+ private readonly HashSet<MemberInfo> composedIds = new HashSet<MemberInfo>();
+ private readonly HashSet<MemberInfo> oneToManyRelations = new HashSet<MemberInfo>();
+ private readonly HashSet<MemberInfo> oneToOneRelations = new HashSet<MemberInfo>();
+ private readonly HashSet<MemberInfo> poids = new HashSet<MemberInfo>();
+ private readonly HashSet<MemberInfo> properties = new HashSet<MemberInfo>();
+ private readonly HashSet<MemberInfo> dynamicComponents = new HashSet<MemberInfo>();
+ private readonly Dictionary<MemberInfo, System.Type> dynamicComponentTemplates = new Dictionary<MemberInfo, System.Type>();
+ private readonly HashSet<MemberInfo> persistentMembers = new HashSet<MemberInfo>();
+ private readonly HashSet<System.Type> rootEntities = new HashSet<System.Type>();
+ private readonly HashSet<MemberInfo> sets = new HashSet<MemberInfo>();
+ private readonly HashSet<System.Type> tablePerClassEntities = new HashSet<System.Type>();
+ private readonly HashSet<System.Type> tablePerClassHierarchyEntities = new HashSet<System.Type>();
+ private readonly HashSet<System.Type> tablePerConcreteClassEntities = new HashSet<System.Type>();
+ private readonly HashSet<MemberInfo> versionProperties = new HashSet<MemberInfo>();
+ private readonly Dictionary<System.Type, HashSet<string>> typeSplitGroups = new Dictionary<System.Type, HashSet<string>>();
+ private readonly Dictionary<MemberInfo, string> memberSplitGroup = new Dictionary<MemberInfo, string>();
+ private readonly HashSet<SplitDefinition> splitDefinitions = new HashSet<SplitDefinition>();
+
+ #region Delayed registrations
+ // To allow a free organization of mappings, especially in presence of a IModelMapper not based exclusivelly on pure declarative mapping, and then
+ // provide a descriptive exception when there are some ambiguity, we have to delay the registration as late as we can
+ // (in practice to the moment we have to give a certain asnwer about the strategy used to represent a System.Type hierarchy).
+ private readonly Queue<System.Action> delayedRootEntityRegistrations = new Queue<System.Action>();
+ private readonly Dictionary<System.Type, List<Action<System.Type>>> delayedEntityRegistrations = new Dictionary<System.Type, List<Action<System.Type>>>();
+
+ #endregion
+
+ public IEnumerable<System.Type> RootEntities
+ {
+ get { return rootEntities; }
+ }
+
+ public IEnumerable<System.Type> Components
+ {
+ get { return components; }
+ }
+
+ public IEnumerable<System.Type> TablePerClassEntities
+ {
+ get { return tablePerClassEntities; }
+ }
+
+ public IEnumerable<System.Type> TablePerClassHierarchyEntities
+ {
+ get { return tablePerClassHierarchyEntities; }
+ }
+
+ public IEnumerable<System.Type> TablePerConcreteClassEntities
+ {
+ get { return tablePerConcreteClassEntities; }
+ }
+
+ public IEnumerable<MemberInfo> OneToOneRelations
+ {
+ get { return oneToOneRelations; }
+ }
+
+ public IEnumerable<MemberInfo> ManyToOneRelations
+ {
+ get { return manyToOneRelations; }
+ }
+
+ public IEnumerable<MemberInfo> ManyToManyRelations
+ {
+ get { return manyToManyRelations; }
+ }
+
+ public IEnumerable<MemberInfo> OneToManyRelations
+ {
+ get { return oneToManyRelations; }
+ }
+
+ public IEnumerable<MemberInfo> Any
+ {
+ get { return any; }
+ }
+
+ public IEnumerable<MemberInfo> Poids
+ {
+ get { return poids; }
+ }
+
+ public IEnumerable<MemberInfo> ComposedIds
+ {
+ get { return composedIds; }
+ }
+
+ public IEnumerable<MemberInfo> VersionProperties
+ {
+ get { return versionProperties; }
+ }
+
+ public IEnumerable<MemberInfo> NaturalIds
+ {
+ get { return naturalIds; }
+ }
+
+ public IEnumerable<MemberInfo> Sets
+ {
+ get { return sets; }
+ }
+
+ public IEnumerable<MemberInfo> Bags
+ {
+ get { return bags; }
+ }
+
+ public IEnumerable<MemberInfo> IdBags
+ {
+ get { return idBags; }
+ }
+
+ public IEnumerable<MemberInfo> Lists
+ {
+ get { return lists; }
+ }
+
+ public IEnumerable<MemberInfo> Arrays
+ {
+ get { return arrays; }
+ }
+
+ public IEnumerable<MemberInfo> Dictionaries
+ {
+ get { return dictionaries; }
+ }
+
+ public IEnumerable<MemberInfo> Properties
+ {
+ get { return properties; }
+ }
+
+ public IEnumerable<MemberInfo> DynamicComponents
+ {
+ get { return dynamicComponents; }
+ }
+
+ public IEnumerable<MemberInfo> PersistentMembers
+ {
+ get { return persistentMembers; }
+ }
+
+ public IEnumerable<SplitDefinition> SplitDefinitions
+ {
+ get { return splitDefinitions; }
+ }
+
+ public IEnumerable<string> GetSplitGroupsFor(System.Type type)
+ {
+ HashSet<string> splitsGroupsIds;
+ if (typeSplitGroups.TryGetValue(type, out splitsGroupsIds))
+ {
+ return splitsGroupsIds;
+ }
+ return Enumerable.Empty<string>();
+ }
+
+ public string GetSplitGroupFor(MemberInfo member)
+ {
+ var memberKey = member.GetMemberFromDeclaringType();
+ string splitGroup;
+ if (memberSplitGroup.TryGetValue(memberKey, out splitGroup))
+ {
+ return splitGroup;
+ }
+ return null;
+ }
+
+ public void AddAsRootEntity(System.Type type)
+ {
+ rootEntities.Add(type);
+ if (IsComponent(type))
+ {
+ throw new MappingException(string.Format("Ambiguous mapping of {0}. It was registered as entity and as component", type.FullName));
+ }
+ }
+
+ public abstract bool IsComponent(System.Type type);
+
+ public void AddAsComponent(System.Type type)
+ {
+ components.Add(type);
+ var rootEntity = GetSingleRootEntityOrNull(type);
+ if (rootEntity != null)
+ {
+ throw new MappingException(string.Format("Ambiguous mapping of {0}. It was registered as entity and as component", type.FullName));
+ }
+ }
+
+ public void AddAsTablePerClassEntity(System.Type type)
+ {
+ AddAsTablePerClassEntity(type, false);
+ }
+
+ protected virtual void AddAsTablePerClassEntity(System.Type type, bool rootEntityMustExists)
+ {
+ if(!rootEntityMustExists)
+ {
+ delayedRootEntityRegistrations.Enqueue(() => System.Array.ForEach(GetRootEntitentitiesOf(type).ToArray(), root=> tablePerClassEntities.Add(root)));
+ EnlistTypeRegistration(type, t => AddAsTablePerClassEntity(t, true));
+ return;
+ }
+ if (IsComponent(type))
+ {
+ throw new MappingException(string.Format("Ambiguous mapping of {0}. It was registered as entity and as component", type.FullName));
+ }
+ var rootEntity = GetSingleRootEntityOrNull(type);
+ if (rootEntity != null)
+ {
+ if (rootEntity.Equals(type))
+ {
+ throw new MappingException(string.Format("Ambiguous mapping of {0}. It was registered as root-entity and as subclass for table-per-class strategy", type.FullName));
+ }
+ if (IsMappedFor(tablePerClassHierarchyEntities, type) || IsMappedFor(tablePerConcreteClassEntities, type))
+ {
+ throw new MappingException(string.Format("Ambiguous mapping of {0}. It was registered with more than one class-hierarchy strategy", type.FullName));
+ }
+ }
+ else
+ {
+ throw new MappingException(string.Format("The root entity for {0} was never registered", type.FullName));
+ }
+ }
+
+ public void AddAsTablePerClassHierarchyEntity(System.Type type)
+ {
+ AddAsTablePerClassHierarchyEntity(type, false);
+ }
+
+ protected virtual void AddAsTablePerClassHierarchyEntity(System.Type type, bool rootEntityMustExists)
+ {
+ if (!rootEntityMustExists)
+ {
+ delayedRootEntityRegistrations.Enqueue(() => System.Array.ForEach(GetRootEntitentitiesOf(type).ToArray(), root => tablePerClassHierarchyEntities.Add(root)));
+ EnlistTypeRegistration(type, t => AddAsTablePerClassHierarchyEntity(t, true));
+ return;
+ }
+
+ if (IsComponent(type))
+ {
+ throw new MappingException(string.Format("Ambiguous mapping of {0}. It was registered as entity and as component", type.FullName));
+ }
+ var rootEntity = GetSingleRootEntityOrNull(type);
+ if (rootEntity != null)
+ {
+ if (rootEntity.Equals(type))
+ {
+ throw new MappingException(string.Format("Ambiguous mapping of {0}. It was registered as root-entity and as subclass for table-per-class-hierarchy strategy", type.FullName));
+ }
+ if (IsMappedFor(tablePerClassEntities, type) || IsMappedFor(tablePerConcreteClassEntities, type))
+ {
+ throw new MappingException(string.Format("Ambiguous mapping of {0}. It was registered with more than one class-hierarchy strategy", type.FullName));
+ }
+ }
+ else
+ {
+ throw new MappingException(string.Format("The root entity for {0} was never registered", type.FullName));
+ }
+ }
+
+ public void AddAsTablePerConcreteClassEntity(System.Type type)
+ {
+ AddAsTablePerConcreteClassEntity(type, false);
+ }
+
+ protected virtual void AddAsTablePerConcreteClassEntity(System.Type type, bool rootEntityMustExists)
+ {
+ if (!rootEntityMustExists)
+ {
+ delayedRootEntityRegistrations.Enqueue(() => System.Array.ForEach(GetRootEntitentitiesOf(type).ToArray(), root => tablePerConcreteClassEntities.Add(root)));
+ EnlistTypeRegistration(type, t => AddAsTablePerConcreteClassEntity(t, true));
+ return;
+ }
+
+ if (IsComponent(type))
+ {
+ throw new MappingException(string.Format("Ambiguous mapping of {0}. It was registered as entity and as component", type.FullName));
+ }
+ var rootEntity = GetSingleRootEntityOrNull(type);
+ if (rootEntity != null)
+ {
+ if (rootEntity.Equals(type))
+ {
+ throw new MappingException(string.Format("Ambiguous mapping of {0}. It was registered as root-entity and as subclass for table-per-concrete-class strategy", type.FullName));
+ }
+ if (IsMappedFor(tablePerClassEntities, type) || IsMappedFor(tablePerClassHierarchyEntities, type))
+ {
+ throw new MappingException(string.Format("Ambiguous mapping of {0}. It was registered with more than one class-hierarchy strategy", type.FullName));
+ }
+ }
+ else
+ {
+ throw new MappingException(string.Format("The root entity for {0} was never registered", type.FullName));
+ }
+ }
+
+ public void AddAsOneToOneRelation(MemberInfo member)
+ {
+ persistentMembers.Add(member);
+ oneToOneRelations.Add(member);
+ }
+
+ public void AddAsManyToOneRelation(MemberInfo member)
+ {
+ persistentMembers.Add(member);
+ manyToOneRelations.Add(member);
+ }
+
+ public void AddAsManyToManyRelation(MemberInfo member)
+ {
+ persistentMembers.Add(member);
+ manyToManyRelations.Add(member);
+ }
+
+ public void AddAsOneToManyRelation(MemberInfo member)
+ {
+ persistentMembers.Add(member);
+ oneToManyRelations.Add(member);
+ }
+
+ public void AddAsAny(MemberInfo member)
+ {
+ persistentMembers.Add(member);
+ any.Add(member);
+ }
+
+ public void AddAsPoid(MemberInfo member)
+ {
+ persistentMembers.Add(member);
+ poids.Add(member);
+ }
+
+ public void AddAsPartOfComposedId(MemberInfo member)
+ {
+ persistentMembers.Add(member);
+ composedIds.Add(member);
+ }
+
+ public void AddAsVersionProperty(MemberInfo member)
+ {
+ persistentMembers.Add(member);
+ versionProperties.Add(member);
+ }
+
+ public void AddAsNaturalId(MemberInfo member)
+ {
+ persistentMembers.Add(member);
+ naturalIds.Add(member);
+ }
+
+ public void AddAsSet(MemberInfo member)
+ {
+ persistentMembers.Add(member);
+ sets.Add(member);
+ }
+
+ public void AddAsBag(MemberInfo member)
+ {
+ persistentMembers.Add(member);
+ bags.Add(member);
+ }
+
+ public void AddAsIdBag(MemberInfo member)
+ {
+ persistentMembers.Add(member);
+ idBags.Add(member);
+ }
+
+ public void AddAsList(MemberInfo member)
+ {
+ persistentMembers.Add(member);
+ lists.Add(member);
+ }
+
+ public void AddAsArray(MemberInfo member)
+ {
+ persistentMembers.Add(member);
+ arrays.Add(member);
+ }
+
+ public void AddAsMap(MemberInfo member)
+ {
+ persistentMembers.Add(member);
+ dictionaries.Add(member);
+ }
+
+ public void AddAsProperty(MemberInfo member)
+ {
+ persistentMembers.Add(member);
+ properties.Add(member);
+ }
+
+ public void AddAsPersistentMember(MemberInfo member)
+ {
+ persistentMembers.Add(member);
+ }
+
+ public void AddAsPropertySplit(SplitDefinition definition)
+ {
+ if (definition == null)
+ {
+ return;
+ }
+ /* Note: if the user "jump/exclude" a class and then map the property in two subclasses the usage of GetMemberFromDeclaringType() may cause a problem
+ for a legal usage... we will see when the case happen */
+ System.Type propertyContainer = definition.On;
+ string splitGroupId = definition.GroupId;
+ MemberInfo member = definition.Member;
+ var memberKey = member.GetMemberFromDeclaringType();
+ string splitGroup;
+ if (!memberSplitGroup.TryGetValue(memberKey, out splitGroup))
+ {
+ AddTypeSplits(propertyContainer, splitGroupId);
+ memberSplitGroup[memberKey] = splitGroupId;
+ }
+
+ splitDefinitions.Add(definition);
+ }
+
+ public void AddAsDynamicComponent(MemberInfo member, System.Type componentTemplate)
+ {
+ persistentMembers.Add(member);
+ dynamicComponents.Add(member);
+ dynamicComponentTemplates[member] = componentTemplate;
+ }
+
+ private void AddTypeSplits(System.Type propertyContainer, string splitGroupId)
+ {
+ HashSet<string> splitsGroupsIds;
+ typeSplitGroups.TryGetValue(propertyContainer, out splitsGroupsIds);
+ if(splitsGroupsIds == null)
+ {
+ splitsGroupsIds = new HashSet<string>();
+ typeSplitGroups[propertyContainer] = splitsGroupsIds;
+ }
+ splitsGroupsIds.Add(splitGroupId);
+ }
+
+ public virtual System.Type GetDynamicComponentTemplate(MemberInfo member)
+ {
+ System.Type template;
+ dynamicComponentTemplates.TryGetValue(member, out template);
+ return template ?? typeof(object);
+ }
+
+ protected System.Type GetSingleRootEntityOrNull(System.Type entityType)
+ {
+ var rootTypes = GetRootEntitentitiesOf(entityType).ToList();
+ if(rootTypes.Count > 1)
+ {
+ var sb = new StringBuilder(1024);
+ sb.AppendLine(string.Format("Ambiguous mapping for {0}. More than one root entities was found:", entityType.FullName));
+ foreach (var rootType in rootTypes.AsEnumerable().Reverse())
+ {
+ sb.AppendLine(rootType.FullName);
+ }
+ sb.AppendLine("Possible solutions:");
+ sb.AppendLine("- Merge the mappings of root entity in the one is representing the real root of the hierarchy.");
+ sb.AppendLine("- Inject a IModelInspector with a logic to discover the real root-entity.");
+ throw new MappingException(sb.ToString());
+ }
+ return rootTypes.SingleOrDefault(IsRootEntity);
+ }
+
+ protected IEnumerable<System.Type> GetRootEntitentitiesOf(System.Type entityType)
+ {
+ if (entityType == null)
+ {
+ yield break;
+ }
+ if(IsRootEntity(entityType))
+ {
+ yield return entityType;
+ }
+ foreach (var type in entityType.GetBaseTypes().Where(IsRootEntity))
+ {
+ yield return type;
+ }
+ }
+
+ public abstract bool IsRootEntity(System.Type entityType);
+
+ protected bool IsMappedForTablePerClassEntities(System.Type type)
+ {
+ return IsMappedFor(tablePerClassEntities, type);
+ }
+
+ protected bool IsMappedForTablePerClassHierarchyEntities(System.Type type)
+ {
+ return IsMappedFor(tablePerClassHierarchyEntities, type);
+ }
+
+ protected bool IsMappedForTablePerConcreteClassEntities(System.Type type)
+ {
+ return IsMappedFor(tablePerConcreteClassEntities, type);
+ }
+
+ private bool IsMappedFor(ICollection<System.Type> explicitMappedEntities, System.Type type)
+ {
+ bool isExplicitMapped = explicitMappedEntities.Contains(type);
+ bool isDerived = false;
+
+ if (!isExplicitMapped)
+ {
+ isDerived = type.GetBaseTypes().Any(explicitMappedEntities.Contains);
+ if (isDerived)
+ {
+ explicitMappedEntities.Add(type);
+ }
+ }
+ return isExplicitMapped || isDerived;
+ }
+
+ protected void EnlistTypeRegistration(System.Type type, Action<System.Type> registration)
+ {
+ List<Action<System.Type>> actions;
+ if (!delayedEntityRegistrations.TryGetValue(type, out actions))
+ {
+ actions = new List<Action<System.Type>>();
+ delayedEntityRegistrations[type] = actions;
+ }
+ actions.Add(registration);
+ }
+
+ protected void ExecuteDelayedTypeRegistration(System.Type type)
+ {
+ ExecuteDelayedRootEntitiesRegistrations();
+ List<Action<System.Type>> actions;
+ if (delayedEntityRegistrations.TryGetValue(type, out actions))
+ {
+ foreach (var action in actions)
+ {
+ action(type);
+ }
+ }
+ }
+
+ protected void ExecuteDelayedRootEntitiesRegistrations()
+ {
+ while (delayedRootEntityRegistrations.Count > 0)
+ {
+ delayedRootEntityRegistrations.Dequeue().Invoke();
+ }
+ }
+
+ protected bool HasDelayedEntityRegistration(System.Type type)
+ {
+ return delayedEntityRegistrations.ContainsKey(type);
+ }
+ }
+}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/ExplicitlyDeclaredModel.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Mapping/ByCode/ExplicitlyDeclaredModel.cs 2011-05-06 14:14:41 UTC (rev 5799)
+++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/ExplicitlyDeclaredModel.cs 2011-05-08 22:59:17 UTC (rev 5800)
@@ -1,470 +1,32 @@
-using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace NHibernate.Mapping.ByCode
{
- public class ExplicitlyDeclaredModel : IModelInspector, IModelExplicitDeclarationsHolder
+ public class ExplicitlyDeclaredModel : AbstractExplicitlyDeclaredModel, IModelInspector
{
- private readonly HashSet<MemberInfo> any = new HashSet<MemberInfo>();
- private readonly HashSet<MemberInfo> arrays = new HashSet<MemberInfo>();
- private readonly HashSet<MemberInfo> bags = new HashSet<MemberInfo>();
- private readonly HashSet<System.Type> components = new HashSet<System.Type>();
- private readonly HashSet<MemberInfo> dictionaries = new HashSet<MemberInfo>();
- private readonly HashSet<MemberInfo> idBags = new HashSet<MemberInfo>();
- private readonly HashSet<MemberInfo> lists = new HashSet<MemberInfo>();
- private readonly HashSet<MemberInfo> manyToManyRelations = new HashSet<MemberInfo>();
- private readonly HashSet<MemberInfo> manyToOneRelations = new HashSet<MemberInfo>();
- private readonly HashSet<MemberInfo> naturalIds = new HashSet<MemberInfo>();
- private readonly HashSet<MemberInfo> composedIds = new HashSet<MemberInfo>();
- private readonly HashSet<MemberInfo> oneToManyRelations = new HashSet<MemberInfo>();
- private readonly HashSet<MemberInfo> oneToOneRelations = new HashSet<MemberInfo>();
- private readonly HashSet<MemberInfo> poids = new HashSet<MemberInfo>();
- private readonly HashSet<MemberInfo> properties = new HashSet<MemberInfo>();
- private readonly HashSet<MemberInfo> dynamicComponents = new HashSet<MemberInfo>();
- private readonly Dictionary<MemberInfo, System.Type> dynamicComponentTemplates = new Dictionary<MemberInfo, System.Type>();
- private readonly HashSet<MemberInfo> persistentMembers = new HashSet<MemberInfo>();
- private readonly HashSet<System.Type> rootEntities = new HashSet<System.Type>();
- private readonly HashSet<MemberInfo> sets = new HashSet<MemberInfo>();
- private readonly HashSet<System.Type> tablePerClassEntities = new HashSet<System.Type>();
- private readonly HashSet<System.Type> tablePerClassHierarchyEntities = new HashSet<System.Type>();
- private readonly HashSet<System.Type> tablePerConcreteClassEntities = new HashSet<System.Type>();
- private readonly HashSet<MemberInfo> versionProperties = new HashSet<MemberInfo>();
- private readonly Dictionary<System.Type, Action<System.Type>> delayedEntityRegistrations = new Dictionary<System.Type, Action<System.Type>>();
- private readonly Dictionary<System.Type, HashSet<string>> typeSplitGroups = new Dictionary<System.Type, HashSet<string>>();
- private readonly Dictionary<MemberInfo, string> memberSplitGroup = new Dictionary<MemberInfo, string>();
- private readonly HashSet<SplitDefinition> splitDefinitions = new HashSet<SplitDefinition>();
-
- #region IModelExplicitDeclarationsHolder Members
-
- public IEnumerable<System.Type> RootEntities
- {
- get { return rootEntities; }
- }
-
- public IEnumerable<System.Type> Components
- {
- get { return components; }
- }
-
- public IEnumerable<System.Type> TablePerClassEntities
- {
- get { return tablePerClassEntities; }
- }
-
- public IEnumerable<System.Type> TablePerClassHierarchyEntities
- {
- get { return tablePerClassHierarchyEntities; }
- }
-
- public IEnumerable<System.Type> TablePerConcreteClassEntities
- {
- get { return tablePerConcreteClassEntities; }
- }
-
- public IEnumerable<MemberInfo> OneToOneRelations
- {
- get { return oneToOneRelations; }
- }
-
- public IEnumerable<MemberInfo> ManyToOneRelations
- {
- get { return manyToOneRelations; }
- }
-
- public IEnumerable<MemberInfo> ManyToManyRelations
- {
- get { return manyToManyRelations; }
- }
-
- public IEnumerable<MemberInfo> OneToManyRelations
- {
- get { return oneToManyRelations; }
- }
-
- public IEnumerable<MemberInfo> Any
- {
- get { return any; }
- }
-
- public IEnumerable<MemberInfo> Poids
- {
- get { return poids; }
- }
-
- public IEnumerable<MemberInfo> ComposedIds
- {
- get { return composedIds; }
- }
-
- public IEnumerable<MemberInfo> VersionProperties
- {
- get { return versionProperties; }
- }
-
- public IEnumerable<MemberInfo> NaturalIds
- {
- get { return naturalIds; }
- }
-
- public IEnumerable<MemberInfo> Sets
- {
- get { return sets; }
- }
-
- public IEnumerable<MemberInfo> Bags
- {
- get { return bags; }
- }
-
- public IEnumerable<MemberInfo> IdBags
- {
- get { return idBags; }
- }
-
- public IEnumerable<MemberInfo> Lists
- {
- get { return lists; }
- }
-
- public IEnumerable<MemberInfo> Arrays
- {
- get { return arrays; }
- }
-
- public IEnumerable<MemberInfo> Dictionaries
- {
- get { return dictionaries; }
- }
-
- public IEnumerable<MemberInfo> Properties
- {
- get { return properties; }
- }
-
- public IEnumerable<MemberInfo> DynamicComponents
- {
- get { return dynamicComponents; }
- }
-
- public IEnumerable<MemberInfo> PersistentMembers
- {
- get { return persistentMembers; }
- }
-
- public IEnumerable<SplitDefinition> SplitDefinitions
- {
- get { return splitDefinitions; }
- }
-
- public IEnumerable<string> GetSplitGroupsFor(System.Type type)
- {
- HashSet<string> splitsGroupsIds;
- if (typeSplitGroups.TryGetValue(type, out splitsGroupsIds))
- {
- return splitsGroupsIds;
- }
- return Enumerable.Empty<string>();
- }
-
- public string GetSplitGroupFor(MemberInfo member)
- {
- var memberKey = member.GetMemberFromDeclaringType();
- string splitGroup;
- if (memberSplitGroup.TryGetValue(memberKey, out splitGroup))
- {
- return splitGroup;
- }
- return null;
- }
-
- public void AddAsRootEntity(System.Type type)
- {
- if (IsComponent(type))
- {
- throw new MappingException(string.Format("Ambiguous mapping of {0}. It was registered as entity and as component", type.FullName));
- }
- rootEntities.Add(type);
- }
-
- public void AddAsComponent(System.Type type)
- {
- var rootEntity = GetRootEntityOrNull(type);
- if (rootEntity != null)
- {
- throw new MappingException(string.Format("Ambiguous mapping of {0}. It was registered as entity and as component", type.FullName));
- }
- components.Add(type);
- }
-
- public void AddAsTablePerClassEntity(System.Type type)
- {
- AddAsTablePerClassEntity(type, false);
- }
-
- public void AddAsTablePerClassEntity(System.Type type, bool rootEntityMustExists)
- {
- if (IsComponent(type))
- {
- throw new MappingException(string.Format("Ambiguous mapping of {0}. It was registered as entity and as component", type.FullName));
- }
- var rootEntity = GetRootEntityOrNull(type);
- if (rootEntity != null)
- {
- if (rootEntity.Equals(type))
- {
- throw new MappingException(string.Format("Ambiguous mapping of {0}. It was registered as root-entity and as subclass for table-per-class strategy", type.FullName));
- }
- if (IsMappedFor(tablePerClassHierarchyEntities, type) || IsMappedFor(tablePerConcreteClassEntities, type))
- {
- throw new MappingException(string.Format("Ambiguous mapping of {0}. It was registered with more than one class-hierarchy strategy", type.FullName));
- }
- tablePerClassEntities.Add(rootEntity);
- }
- else
- {
- if(rootEntityMustExists)
- {
- throw new MappingException(string.Format("The root entity for {0} was never registered", type.FullName));
- }
- EnlistTypeRegistration(type, t => AddAsTablePerClassEntity(t, true));
- }
- }
-
- public void AddAsTablePerClassHierarchyEntity(System.Type type)
- {
- AddAsTablePerClassHierarchyEntity(type, false);
- }
-
- public void AddAsTablePerClassHierarchyEntity(System.Type type, bool rootEntityMustExists)
- {
- if (IsComponent(type))
- {
- throw new MappingException(string.Format("Ambiguous mapping of {0}. It was registered as entity and as component", type.FullName));
- }
- var rootEntity = GetRootEntityOrNull(type);
- if (rootEntity != null)
- {
- if (rootEntity.Equals(type))
- {
- throw new MappingException(string.Format("Ambiguous mapping of {0}. It was registered as root-entity and as subclass for table-per-class-hierarchy strategy", type.FullName));
- }
- if (IsMappedFor(tablePerClassEntities, type) || IsMappedFor(tablePerConcreteClassEntities, type))
- {
- throw new MappingException(string.Format("Ambiguous mapping of {0}. It was registered with more than one class-hierarchy strategy", type.FullName));
- }
- tablePerClassHierarchyEntities.Add(rootEntity);
- }
- else
- {
- if (rootEntityMustExists)
- {
- throw new MappingException(string.Format("The root entity for {0} was never registered", type.FullName));
- }
- EnlistTypeRegistration(type, t => AddAsTablePerClassHierarchyEntity(t, true));
- }
- }
-
- public void AddAsTablePerConcreteClassEntity(System.Type type)
- {
- AddAsTablePerConcreteClassEntity(type, false);
- }
-
- public void AddAsTablePerConcreteClassEntity(System.Type type, bool rootEntityMustExists)
- {
- if (IsComponent(type))
- {
- throw new MappingException(string.Format("Ambiguous mapping of {0}. It was registered as entity and as component", type.FullName));
- }
- var rootEntity = GetRootEntityOrNull(type);
- if (rootEntity != null)
- {
- if (rootEntity.Equals(type))
- {
- throw new MappingException(string.Format("Ambiguous mapping of {0}. It was registered as root-entity and as subclass for table-per-concrete-class strategy", type.FullName));
- }
- if (IsMappedFor(tablePerClassEntities, type) || IsMappedFor(tablePerClassHierarchyEntities, type))
- {
- throw new MappingException(string.Format("Ambiguous mapping of {0}. It was registered with more than one class-hierarchy strategy", type.FullName));
- }
- tablePerConcreteClassEntities.Add(rootEntity);
- }
- else
- {
- if (rootEntityMustExists)
- {
- throw new MappingException(string.Format("The root entity for {0} was never registered", type.FullName));
- }
- EnlistTypeRegistration(type, t => AddAsTablePerConcreteClassEntity(t, true));
- }
- }
-
- public void AddAsOneToOneRelation(MemberInfo member)
- {
- persistentMembers.Add(member);
- oneToOneRelations.Add(member);
- }
-
- public void AddAsManyToOneRelation(MemberInfo member)
- {
- persistentMembers.Add(member);
- manyToOneRelations.Add(member);
- }
-
- public void AddAsManyToManyRelation(MemberInfo member)
- {
- persistentMembers.Add(member);
- manyToManyRelations.Add(member);
- }
-
- public void AddAsOneToManyRelation(MemberInfo member)
- {
- persistentMembers.Add(member);
- oneToManyRelations.Add(member);
- }
-
- public void AddAsAny(MemberInfo member)
- {
- persistentMembers.Add(member);
- any.Add(member);
- }
-
- public void AddAsPoid(MemberInfo member)
- {
- persistentMembers.Add(member);
- poids.Add(member);
- }
-
- public void AddAsPartOfComposedId(MemberInfo member)
- {
- persistentMembers.Add(member);
- composedIds.Add(member);
- }
-
- public void AddAsVersionProperty(MemberInfo member)
- {
- persistentMembers.Add(member);
- versionProperties.Add(member);
- }
-
- public void AddAsNaturalId(MemberInfo member)
- {
- persistentMembers.Add(member);
- naturalIds.Add(member);
- }
-
- public void AddAsSet(MemberInfo member)
- {
- persistentMembers.Add(member);
- sets.Add(member);
- }
-
- public void AddAsBag(MemberInfo member)
- {
- persistentMembers.Add(member);
- bags.Add(member);
- }
-
- public void AddAsIdBag(MemberInfo member)
- {
- persistentMembers.Add(member);
- idBags.Add(member);
- }
-
- public void AddAsList(MemberInfo member)
- {
- persistentMembers.Add(member);
- lists.Add(member);
- }
-
- public void AddAsArray(MemberInfo member)
- {
- persistentMembers.Add(member);
- arrays.Add(member);
- }
-
- public void AddAsMap(MemberInfo member)
- {
- persistentMembers.Add(member);
- dictionaries.Add(member);
- }
-
- public void AddAsProperty(MemberInfo member)
- {
- persistentMembers.Add(member);
- properties.Add(member);
- }
-
- public void AddAsPersistentMember(MemberInfo member)
- {
- persistentMembers.Add(member);
- }
-
- public void AddAsPropertySplit(SplitDefinition definition)
- {
- if (definition == null)
- {
- return;
- }
- /* Note: if the user "jump/exclude" a class and then map the property in two subclasses the usage of GetMemberFromDeclaringType() may cause a problem
- for a legal usage... we will see when the case happen */
- System.Type propertyContainer = definition.On;
- string splitGroupId = definition.GroupId;
- MemberInfo member = definition.Member;
- var memberKey = member.GetMemberFromDeclaringType();
- string splitGroup;
- if (!memberSplitGroup.TryGetValue(memberKey, out splitGroup))
- {
- AddTypeSplits(propertyContainer, splitGroupId);
- memberSplitGroup[memberKey] = splitGroupId;
- }
-
- splitDefinitions.Add(definition);
- }
-
- public void AddAsDynamicComponent(MemberInfo member, System.Type componentTemplate)
- {
- persistentMembers.Add(member);
- dynamicComponents.Add(member);
- dynamicComponentTemplates[member] = componentTemplate;
- }
-
- private void AddTypeSplits(System.Type propertyContainer, string splitGroupId)
- {
- HashSet<string> splitsGroupsIds;
- typeSplitGroups.TryGetValue(propertyContainer, out splitsGroupsIds);
- if(splitsGroupsIds == null)
- {
- splitsGroupsIds = new HashSet<string>();
- typeSplitGroups[propertyContainer] = splitsGroupsIds;
- }
- splitsGroupsIds.Add(splitGroupId);
- }
-
- #endregion
-
#region Implementation of IModelInspector
- public virtual bool IsRootEntity(System.Type type)
+ public override bool IsRootEntity(System.Type type)
{
- return rootEntities.Contains(type);
+ return RootEntities.Contains(type);
}
- public virtual bool IsComponent(System.Type type)
+ public override bool IsComponent(System.Type type)
{
- return components.Contains(type);
+ return Components.Contains(type);
}
public virtual bool IsEntity(System.Type type)
{
- return rootEntities.Contains(type) || type.GetBaseTypes().Any(t => rootEntities.Contains(t)) || HasDelayedEntityRegistration(type);
+ return RootEntities.Contains(type) || type.GetBaseTypes().Any(t => RootEntities.Contains(t)) || HasDelayedEntityRegistration(type);
}
public virtual bool IsTablePerClass(System.Type type)
{
ExecuteDelayedTypeRegistration(type);
- return IsMappedFor(tablePerClassEntities, type);
+ return IsMappedForTablePerClassEntities(type);
}
public virtual bool IsTablePerClassSplit(System.Type type, object splitGroupId, MemberInfo member)
@@ -475,166 +37,110 @@
public virtual bool IsTablePerClassHierarchy(System.Type type)
{
ExecuteDelayedTypeRegistration(type);
- return IsMappedFor(tablePerClassHierarchyEntities, type);
+ return IsMappedForTablePerClassHierarchyEntities(type);
}
public virtual bool IsTablePerConcreteClass(System.Type type)
{
ExecuteDelayedTypeRegistration(type);
- return IsMappedFor(tablePerConcreteClassEntities, type);
+ return IsMappedForTablePerConcreteClassEntities(type);
}
public virtual bool IsOneToOne(MemberInfo member)
{
- return oneToOneRelations.Contains(member);
+ return OneToOneRelations.Contains(member);
}
public virtual bool IsManyToOne(MemberInfo member)
{
- return manyToOneRelations.Contains(member);
+ return ManyToOneRelations.Contains(member);
}
public virtual bool IsManyToMany(MemberInfo member)
{
- return manyToManyRelations.Contains(member);
+ return ManyToManyRelations.Contains(member);
}
public virtual bool IsOneToMany(MemberInfo member)
{
- return oneToManyRelations.Contains(member);
+ return OneToManyRelations.Contains(member);
}
public virtual bool IsAny(MemberInfo member)
{
- return any.Contains(member);
+ return Any.Contains(member);
}
public virtual bool IsPersistentId(MemberInfo member)
{
- return poids.Contains(member);
+ return Poids.Contains(member);
}
public bool IsMemberOfComposedId(MemberInfo member)
{
- return composedIds.Contains(member);
+ return ComposedIds.Contains(member);
}
public virtual bool IsVersion(MemberInfo member)
{
- return versionProperties.Contains(member);
+ return VersionProperties.Contains(member);
}
public virtual bool IsMemberOfNaturalId(MemberInfo member)
{
- return naturalIds.Contains(member);
+ return NaturalIds.Contains(member);
}
public virtual bool IsPersistentProperty(MemberInfo member)
{
- return persistentMembers.Contains(member);
+ return PersistentMembers.Contains(member);
}
public virtual bool IsSet(MemberInfo role)
{
- return sets.Contains(role);
+ return Sets.Contains(role);
}
public virtual bool IsBag(MemberInfo role)
{
- return bags.Contains(role);
+ return Bags.Contains(role);
}
public virtual bool IsIdBag(MemberInfo role)
{
- return idBags.Contains(role);
+ return IdBags.Contains(role);
}
public virtual bool IsList(MemberInfo role)
{
- return lists.Contains(role);
+ return Lists.Contains(role);
}
public virtual bool IsArray(MemberInfo role)
{
- return arrays.Contains(role);
+ return Arrays.Contains(role);
}
public virtual bool IsDictionary(MemberInfo role)
{
- return dictionaries.Contains(role);
+ return Dictionaries.Contains(role);
}
public virtual bool IsProperty(MemberInfo member)
{
- return properties.Contains(member);
+ return Properties.Contains(member);
}
- public bool IsDynamicComponent(MemberInfo member)
+ public virtual bool IsDynamicComponent(MemberInfo member)
{
- return dynamicComponents.Contains(member);
+ return DynamicComponents.Contains(member);
}
- public System.Type GetDynamicComponentTemplate(MemberInfo member)
+ public virtual IEnumerable<string> GetPropertiesSplits(System.Type type)
{
- System.Type template;
- dynamicComponentTemplates.TryGetValue(member, out template);
- return template ?? typeof(object);
- }
-
- public IEnumerable<string> GetPropertiesSplits(System.Type type)
- {
return GetSplitGroupsFor(type);
}
#endregion
-
- protected System.Type GetRootEntityOrNull(System.Type entityType)
- {
- if (entityType == null)
- {
- return null;
- }
- if (IsRootEntity(entityType))
- {
- return entityType;
- }
- return entityType.GetBaseTypes().SingleOrDefault(IsRootEntity);
- }
-
- protected bool IsMappedFor(ICollection<System.Type> explicitMappedEntities, System.Type type)
- {
- bool isExplicitMapped = explicitMappedEntities.Contains(type);
- bool isDerived = false;
-
- if (!isExplicitMapped)
- {
- isDerived = type.GetBaseTypes().Any(explicitMappedEntities.Contains);
- if (isDerived)
- {
- explicitMappedEntities.Add(type);
- }
- }
- return isExplicitMapped || isDerived;
- }
-
- protected void EnlistTypeRegistration(System.Type type, Action<System.Type> registration)
- {
- delayedEntityRegistrations.Add(type, registration);
- }
-
- protected void ExecuteDelayedTypeRegistration(System.Type type)
- {
- Action<System.Type> registration;
- if(delayedEntityRegistrations.TryGetValue(type, out registration))
- {
- delayedEntityRegistrations.Remove(type);
- registration(type);
- }
- }
-
- protected bool HasDelayedEntityRegistration(System.Type type)
- {
- return delayedEntityRegistrations.ContainsKey(type);
- }
}
}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/SimpleModelInspector.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Mapping/ByCode/SimpleModelInspector.cs 2011-05-06 14:14:41 UTC (rev 5799)
+++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/SimpleModelInspector.cs 2011-05-08 22:59:17 UTC (rev 5800)
@@ -11,8 +11,151 @@
/// </summary>
public class SimpleModelInspector : IModelInspector, IModelExplicitDeclarationsHolder
{
- private readonly ExplicitlyDeclaredModel declaredModel = new ExplicitlyDeclaredModel();
+ private class MixinDeclaredModel : AbstractExplicitlyDeclaredModel
+ {
+ private readonly IModelInspector inspector;
+ public MixinDeclaredModel(IModelInspector inspector)
+ {
+ this.inspector = inspector;
+ }
+
+ public override bool IsComponent(System.Type type)
+ {
+ return Components.Contains(type);
+ }
+
+ public override bool IsRootEntity(System.Type entityType)
+ {
+ return inspector.IsRootEntity(entityType);
+ }
+
+ public bool IsEntity(System.Type type)
+ {
+ return RootEntities.Contains(type) || type.GetBaseTypes().Any(t => RootEntities.Contains(t)) || HasDelayedEntityRegistration(type);
+ }
+
+ public bool IsTablePerClass(System.Type type)
+ {
+ ExecuteDelayedTypeRegistration(type);
+ return IsMappedForTablePerClassEntities(type);
+ }
+
+ public bool IsTablePerClassSplit(System.Type type, object splitGroupId, MemberInfo member)
+ {
+ return Equals(splitGroupId, GetSplitGroupFor(member));
+ }
+
+ public bool IsTablePerClassHierarchy(System.Type type)
+ {
+ ExecuteDelayedTypeRegistration(type);
+ return IsMappedForTablePerClassHierarchyEntities(type);
+ }
+
+ public bool IsTablePerConcreteClass(System.Type type)
+ {
+ ExecuteDelayedTypeRegistration(type);
+ return IsMappedForTablePerConcreteClassEntities(type);
+ }
+
+ public bool IsOneToOne(MemberInfo member)
+ {
+ return OneToOneRelations.Contains(member);
+ }
+
+ public bool IsManyToOne(MemberInfo member)
+ {
+ return ManyToOneRelations.Contains(member);
+ }
+
+ public bool IsManyToMany(MemberInfo member)
+ {
+ return ManyToManyRelations.Contains(member);
+ }
+
+ public bool IsOneToMany(MemberInfo member)
+ {
+ return OneToManyRelations.Contains(member);
+ }
+
+ public bool IsAny(MemberInfo member)
+ {
+ return Any.Contains(member);
+ }
+
+ public bool IsPersistentId(MemberInfo member)
+ {
+ return Poids.Contains(member);
+ }
+
+ public bool IsMemberOfComposedId(MemberInfo member)
+ {
+ return ComposedIds.Contains(member);
+ }
+
+ public bool IsVersion(MemberInfo member)
+ {
+ return VersionProperties.Contains(member);
+ }
+
+ public bool IsMemberOfNaturalId(MemberInfo member)
+ {
+ return NaturalIds.Contains(member);
+ }
+
+ public bool IsPersistentProperty(MemberInfo member)
+ {
+ return PersistentMembers.Contains(member);
+ }
+
+ public bool IsSet(MemberInfo role)
+ {
+ return Sets.Contains(role);
+ }
+
+ public bool IsBag(MemberInfo role)
+ {
+ return Bags.Contains(role);
+ }
+
+ public bool IsIdBag(MemberInfo role)
+ {
+ return IdBags.Contains(role);
+ }
+
+ public bool IsList(MemberInfo role)
+ {
+ return Lists.Contains(role);
+ }
+
+ public bool IsArray(MemberInfo role)
+ {
+ return Arrays.Contains(role);
+ }
+
+ public bool IsDictionary(MemberInfo role)
+ {
+ return Dictionaries.Contains(role);
+ }
+
+ public bool IsProperty(MemberInfo member)
+ {
+ return Properties.Contains(member);
+ }
+
+ public bool IsDynamicComponent(MemberInfo member)
+ {
+ return DynamicComponents.Contains(member);
+ }
+
+ public IEnumerable<string> GetPropertiesSplits(System.Type type)
+ {
+ return GetSplitGroupsFor(type);
+ }
+ }
+
+ private readonly MixinDeclaredModel declaredModel;
+
private Func<System.Type, bool, bool> isEntity = (t, declared) => declared;
private Func<System.Type, bool, bool> isRootEntity;
private Func<System.Type, bool, bool> isTablePerClass;
@@ -56,11 +199,12 @@
isDictionary = (m, declared) => declared || MatchCollection(m, MatchDictionaryMember);
isManyToOne = (m, declared) => declared || MatchManyToOne(m);
isOneToMany = (m, declared) => declared || MatchOneToMany(m);
+ declaredModel = new MixinDeclaredModel(this);
}
private bool MatchRootEntity(System.Type type)
{
- return type.IsClass && typeof(object).Equals(type.BaseType);
+ return type.IsClass && typeof(object).Equals(type.BaseType) && ((IModelInspector)this).IsEntity(type);
}
private bool MatchTablePerClass(System.Type type)
@@ -213,6 +357,10 @@
const BindingFlags flattenHierarchyMembers =
BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
+ if (declaredModel.IsEntity(subject))
+ {
+ return false;
+ }
var modelInspector = (IModelInspector) this;
return !subject.IsEnum && (subject.Namespace == null || !subject.Namespace.StartsWith("System")) /* hack */
&& !modelInspector.IsEntity(subject)
@@ -224,7 +372,10 @@
{
const BindingFlags flattenHierarchyMembers =
BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
-
+ if(declaredModel.Components.Contains(subject))
+ {
+ return false;
+ }
var modelInspector = (IModelInspector) this;
return subject.IsClass &&
subject.GetProperties(flattenHierarchyMembers).Cast<MemberInfo>().Concat(subject.GetFields(flattenHierarchyMembers)).Any(m => modelInspector.IsPersistentId(m));
@@ -488,13 +639,13 @@
bool IModelInspector.IsRootEntity(System.Type type)
{
- bool declaredResult = declaredModel.IsRootEntity(type);
+ bool declaredResult = declaredModel.RootEntities.Contains(type);
return isRootEntity(type, declaredResult);
}
bool IModelInspector.IsComponent(System.Type type)
{
- bool declaredResult = declaredModel.IsComponent(type);
+ bool declaredResult = declaredModel.Components.Contains(type);
return isComponent(type, declaredResult);
}
Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2011-05-06 14:14:41 UTC (rev 5799)
+++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2011-05-08 22:59:17 UTC (rev 5800)
@@ -284,6 +284,7 @@
<Compile Include="Mapping\Any.cs" />
<Compile Include="Mapping\Array.cs" />
<Compile Include="Mapping\Bag.cs" />
+ <Compile Include="Mapping\ByCode\AbstractExplicitlyDeclaredModel.cs" />
<Compile Include="Mapping\ByCode\CacheInclude.cs" />
<Compile Include="Mapping\ByCode\CacheUsage.cs" />
<Compile Include="Mapping\ByCode\Cascade.cs" />
Modified: trunk/nhibernate/src/NHibernate.Test/MappingByCode/ExplicitlyDeclaredModelTests/ComponentMappingRegistrationTests.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/MappingByCode/ExplicitlyDeclaredModelTests/ComponentMappingRegistrationTests.cs 2011-05-06 14:14:41 UTC (rev 5799)
+++ trunk/nhibernate/src/NHibernate.Test/MappingByCode/ExplicitlyDeclaredModelTests/ComponentMappingRegistrationTests.cs 2011-05-08 22:59:17 UTC (rev 5800)
@@ -42,27 +42,39 @@
public void WhenRegisteredAsComponetThenCantRegisterAsJoinedSubclass()
{
var inspector = new ExplicitlyDeclaredModel();
- inspector.AddAsComponent(typeof(MyComponent));
+ inspector.AddAsComponent(typeof (MyComponent));
- inspector.Executing(x => x.AddAsTablePerClassEntity(typeof(MyComponent))).Throws<MappingException>();
+ Executing.This(() =>
+ {
+ inspector.AddAsTablePerClassEntity(typeof (MyComponent));
+ inspector.IsTablePerClass(typeof (MyComponent));
+ }).Should().Throw<MappingException>();
}
[Test]
public void WhenRegisteredAsComponetThenCantRegisterAsSubclass()
{
var inspector = new ExplicitlyDeclaredModel();
- inspector.AddAsComponent(typeof(MyComponent));
+ inspector.AddAsComponent(typeof (MyComponent));
- inspector.Executing(x => x.AddAsTablePerClassHierarchyEntity(typeof(MyComponent))).Throws<MappingException>();
+ Executing.This(() =>
+ {
+ inspector.AddAsTablePerClassHierarchyEntity(typeof (MyComponent));
+ inspector.IsTablePerClassHierarchy(typeof (MyComponent));
+ }).Should().Throw<MappingException>();
}
[Test]
public void WhenRegisteredAsComponetThenCantRegisterAsUnionSubclass()
{
var inspector = new ExplicitlyDeclaredModel();
- inspector.AddAsComponent(typeof(MyComponent));
+ inspector.AddAsComponent(typeof (MyComponent));
- inspector.Executing(x => x.AddAsTablePerConcreteClassEntity(typeof(MyComponent))).Throws<MappingException>();
+ Executing.This(() =>
+ {
+ inspector.AddAsTablePerConcreteClassEntity(typeof (MyComponent));
+ inspector.IsTablePerConcreteClass(typeof (MyComponent));
+ }).Should().Throw<MappingException>();
}
}
}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate.Test/MappingByCode/ExplicitlyDeclaredModelTests/JoinedSubclassMappingStrategyTests.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/MappingByCode/ExplicitlyDeclaredModelTests/JoinedSubclassMappingStrategyTests.cs 2011-05-06 14:14:41 UTC (rev 5799)
+++ trunk/nhibernate/src/NHibernate.Test/MappingByCode/ExplicitlyDeclaredModelTests/JoinedSubclassMappingStrategyTests.cs 2011-05-08 22:59:17 UTC (rev 5800)
@@ -47,20 +47,28 @@
public void WhenRegisteredAsJoinedSubclassThenCantRegisterAsSubclass()
{
var inspector = new ExplicitlyDeclaredModel();
- inspector.AddAsRootEntity(typeof(MyClass));
- inspector.AddAsTablePerClassEntity(typeof(Inherited1));
+ inspector.AddAsRootEntity(typeof (MyClass));
+ inspector.AddAsTablePerClassEntity(typeof (Inherited1));
- inspector.Executing(x => x.AddAsTablePerClassHierarchyEntity(typeof(Inherited1))).Throws<MappingException>();
+ Executing.This(() =>
+ {
+ inspector.AddAsTablePerClassHierarchyEntity(typeof (Inherited1));
+ inspector.IsTablePerClass(typeof (Inherited1));
+ }).Should().Throw<MappingException>();
}
[Test]
public void WhenRegisteredAsJoinedSubclassThenCantRegisterAsUnionSubclass()
{
var inspector = new ExplicitlyDeclaredModel();
- inspector.AddAsRootEntity(typeof(MyClass));
- inspector.AddAsTablePerClassEntity(typeof(Inherited1));
+ inspector.AddAsRootEntity(typeof (MyClass));
+ inspector.AddAsTablePerClassEntity(typeof (Inherited1));
- inspector.Executing(x => x.AddAsTablePerConcreteClassEntity(typeof(Inherited1))).Throws<MappingException>();
+ Executing.This(() =>
+ {
+ inspector.AddAsTablePerConcreteClassEntity(typeof (Inherited1));
+ inspector.IsTablePerClass(typeof (Inherited1));
+ }).Should().Throw<MappingException>();
}
[Test]
Modified: trunk/nhibernate/src/NHibernate.Test/MappingByCode/ExplicitlyDeclaredModelTests/RootClassMappingStrategyTests.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/MappingByCode/ExplicitlyDeclaredModelTests/RootClassMappingStrategyTests.cs 2011-05-06 14:14:41 UTC (rev 5799)
+++ trunk/nhibernate/src/NHibernate.Test/MappingByCode/ExplicitlyDeclaredModelTests/RootClassMappingStrategyTests.cs 2011-05-08 22:59:17 UTC (rev 5800)
@@ -103,24 +103,36 @@
public void WhenRegisteredAsRootThenCantRegisterAsSubclass()
{
var inspector = new ExplicitlyDeclaredModel();
- inspector.AddAsRootEntity(typeof(MyClass));
- inspector.Executing(x=> x.AddAsTablePerClassEntity(typeof(MyClass))).Throws<MappingException>();
+ inspector.AddAsRootEntity(typeof (MyClass));
+ Executing.This(() =>
+ {
+ inspector.AddAsTablePerClassHierarchyEntity(typeof (MyClass));
+ inspector.IsTablePerClassHierarchy(typeof (MyClass));
+ }).Should().Throw<MappingException>();
}
[Test]
public void WhenRegisteredAsRootThenCantRegisterAsJoinedSubclass()
{
var inspector = new ExplicitlyDeclaredModel();
- inspector.AddAsRootEntity(typeof(MyClass));
- inspector.Executing(x => x.AddAsTablePerClassEntity(typeof(MyClass))).Throws<MappingException>();
+ inspector.AddAsRootEntity(typeof (MyClass));
+ Executing.This(() =>
+ {
+ inspector.AddAsTablePerClassEntity(typeof (MyClass));
+ inspector.IsTablePerClass(typeof (MyClass));
+ }).Should().Throw<MappingException>();
}
[Test]
public void WhenRegisteredAsRootThenCantRegisterAsUnionSubclass()
{
var inspector = new ExplicitlyDeclaredModel();
- inspector.AddAsRootEntity(typeof(MyClass));
- inspector.Executing(x => x.AddAsTablePerClassEntity(typeof(MyClass))).Throws<MappingException>();
+ inspector.AddAsRootEntity(typeof (MyClass));
+ Executing.This(() =>
+ {
+ inspector.AddAsTablePerConcreteClassEntity(typeof (MyClass));
+ inspector.IsTablePerClass(typeof (MyClass));
+ }).Should().Throw<MappingException>();
}
[Test]
@@ -131,5 +143,18 @@
inspector.IsEntity(typeof(MyClass)).Should().Be.True();
}
+
+ [Test]
+ public void WhenMultipleRootRegisteredThenThrowsMappingException()
+ {
+ var inspector = new ExplicitlyDeclaredModel();
+ inspector.AddAsRootEntity(typeof(MyClass));
+ inspector.AddAsRootEntity(typeof(Inherited1));
+ Executing.This(()=>
+ {
+ inspector.AddAsTablePerClassEntity(typeof(Inherited2));
+ inspector.IsTablePerClass(typeof(Inherited2));
+ }).Should().Throw<MappingException>();
+ }
}
}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate.Test/MappingByCode/ExplicitlyDeclaredModelTests/SubclassMappingStrategyTests.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/MappingByCode/ExplicitlyDeclaredModelTests/SubclassMappingStrategyTests.cs 2011-05-06 14:14:41 UTC (rev 5799)
+++ trunk/nhibernate/src/NHibernate.Test/MappingByCode/ExplicitlyDeclaredModelTests/SubclassMappingStrategyTests.cs 2011-05-08 22:59:17 UTC (rev 5800)
@@ -50,17 +50,25 @@
inspector.AddAsRootEntity(typeof(MyClass));
inspector.AddAsTablePerClassHierarchyEntity(typeof(Inherited1));
- inspector.Executing(x => x.AddAsTablePerClassEntity(typeof(Inherited1))).Throws<MappingException>();
+ Executing.This(() =>
+ {
+ inspector.AddAsTablePerClassEntity(typeof(Inherited1));
+ inspector.IsTablePerClass(typeof(Inherited1));
+ }).Should().Throw<MappingException>();
}
[Test]
public void WhenRegisteredAsSubclassThenCantRegisterAsUnionSubclass()
{
var inspector = new ExplicitlyDeclaredModel();
- inspector.AddAsRootEntity(typeof(MyClass));
- inspector.AddAsTablePerClassHierarchyEntity(typeof(Inherited1));
+ inspector.AddAsRootEntity(typeof (MyClass));
+ inspector.AddAsTablePerClassHierarchyEntity(typeof (Inherited1));
- inspector.Executing(x => x.AddAsTablePerConcreteClassEntity(typeof(Inherited1))).Throws<MappingException>();
+ Executing.This(() =>
+ {
+ inspector.AddAsTablePerConcreteClassEntity(typeof (Inherited1));
+ inspector.IsTablePerClassHierarchy(typeof (Inherited1));
+ }).Should().Throw<MappingException>();
}
[Test]
Modified: trunk/nhibernate/src/NHibernate.Test/MappingByCode/ExplicitlyDeclaredModelTests/UnionSubclassMappingStrategyTests.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/MappingByCode/ExplicitlyDeclaredModelTests/UnionSubclassMappingStrategyTests.cs 2011-05-06 14:14:41 UTC (rev 5799)
+++ trunk/nhibernate/src/NHibernate.Test/MappingByCode/ExplicitlyDeclaredModelTests/UnionSubclassMappingStrategyTests.cs 2011-05-08 22:59:17 UTC (rev 5800)
@@ -47,20 +47,28 @@
public void WhenRegisteredAsUnionSubclassThenCantRegisterAsSubclass()
{
var inspector = new ExplicitlyDeclaredModel();
- inspector.AddAsRootEntity(typeof(MyClass));
- inspector.AddAsTablePerConcreteClassEntity(typeof(Inherited1));
+ inspector.AddAsRootEntity(typeof (MyClass));
+ inspector.AddAsTablePerConcreteClassEntity(typeof (Inherited1));
- inspector.Executing(x => x.AddAsTablePerClassHierarchyEntity(typeof(Inherited1))).Throws<MappingException>();
+ Executing.This(() =>
+ {
+ inspector.AddAsTablePerClassHierarchyEntity(typeof (Inherited1));
+ inspector.IsTablePerConcreteClass(typeof (Inherited1));
+ }).Should().Throw<MappingException>();
}
[Test]
public void WhenRegisteredAsUnionSubclassThenCantRegisterAsJoinedSubclass()
{
var inspector = new ExplicitlyDeclaredModel();
- inspector.AddAsRootEntity(typeof(MyClass));
- inspector.AddAsTablePerConcreteClassEntity(typeof(Inherited1));
+ inspector.AddAsRootEntity(typeof (MyClass));
+ inspector.AddAsTablePerConcreteClassEntity(typeof (Inherited1));
- inspector.Executing(x => x.AddAsTablePerClassEntity(typeof(Inherited1))).Throws<MappingException>();
+ Executing.This(() =>
+ {
+ inspector.AddAsTablePerClassEntity(typeof (Inherited1));
+ inspector.IsTablePerConcreteClass(typeof (Inherited1));
+ }).Should().Throw<MappingException>();
}
[Test]
Added: trunk/nhibernate/src/NHibernate.Test/MappingByCode/MixAutomapping/CallCustomConditions.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/MappingByCode/MixAutomapping/CallCustomConditions.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/MappingByCode/MixAutomapping/CallCustomConditions.cs 2011-05-08 22:59:17 UTC (rev 5800)
@@ -0,0 +1,68 @@
+using System;
+using NHibernate.Mapping.ByCode;
+using NUnit.Framework;
+using SharpTestsEx;
+
+namespace NHibernate.Test.MappingByCode.MixAutomapping
+{
+ public class CallCustomConditions
+ {
+ public enum ActivityType
+ {
+ Form = 1,
+ Custom = 2,
+ Email = 3
+ }
+
+ private class Activity : Entity
+ {
+ public virtual string Title { get; set; }
+ }
+
+ private interface IEntity<T>
+ {
+ T Id { get; }
+ }
+
+ private class Entity : IEntity<Guid>
+ {
+ #region IEntity<Guid> Members
+
+ public virtual Guid Id { get; private set; }
+
+ #endregion
+ }
+
+ private class FormActivity : Activity { }
+
+ [Test]
+ public void WhenCustomizeConditionsThenUseCustomConditionsToRecognizeRootEntities()
+ {
+ System.Type baseEntityType = typeof(Entity);
+ var inspector = new SimpleModelInspector();
+ inspector.IsEntity((t, declared) => baseEntityType.IsAssignableFrom(t) && baseEntityType != t && !t.IsInterface);
+ inspector.IsRootEntity((t, declared) => baseEntityType.Equals(t.BaseType));
+
+ var mapper = new ModelMapper(inspector);
+ mapper.Class<Entity>(map => map.Id(x => x.Id,
+ m =>
+ {
+ m.Generator(Generators.Guid);
+ m.Column("ID");
+ }));
+
+ mapper.Class<Activity>(map =>
+ {
+ map.Discriminator(dm =>
+ {
+ dm.Column("DISCRIMINATOR_TYPE");
+ dm.NotNullable(true);
+ });
+ map.DiscriminatorValue(0);
+ });
+ mapper.Subclass<FormActivity>(map => map.DiscriminatorValue(1));
+
+ mapper.Executing(m=> m.CompileMappingFor(new[] { typeof(Activity), typeof(FormActivity) })).NotThrows();
+ }
+ }
+}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-05-06 14:14:41 UTC (rev 5799)
+++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-05-08 22:59:17 UTC (rev 5800)
@@ -585,6 +585,7 @@
<Compile Include="MappingByCode\MappersTests\UnionSubclassMapperTests\TablesSincronizationTests.cs" />
<Compile Include="MappingByCode\MixAutomapping\ArrayCollectionTests.cs" />
<Compile Include="MappingByCode\MixAutomapping\BagCollectionTests.cs" />
+ <Compile Include="MappingByCode\MixAutomapping\CallCustomConditions.cs" />
<Compile Include="MappingByCode\MixAutomapping\Compone...
[truncated message content] |