From: <fab...@us...> - 2011-04-22 14:14:33
|
Revision: 5736 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5736&view=rev Author: fabiomaulo Date: 2011-04-22 14:14:26 +0000 (Fri, 22 Apr 2011) Log Message: ----------- dynamic-component mapping first try Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Mapping/ByCode/ExplicitlyDeclaredModel.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/FakeModelExplicitDeclarationsHolder.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/IModelExplicitDeclarationsHolder.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/IModelInspector.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersHolder.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/PropertyContainerCustomizer.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/DefaultCandidatePersistentMembersProvider.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/ExplicitDeclarationsHolder.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/ICustomizersHolder.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/ModelExplicitDeclarationsHolderExtensions.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/ModelMapper.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/SimpleModelInspector.cs trunk/nhibernate/src/NHibernate/NHibernate.csproj trunk/nhibernate/src/NHibernate.Test/MappingByCode/ModelExplicitDeclarationsHolderMergeTest.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/DynamicComponentCustomizer.cs trunk/nhibernate/src/NHibernate.Test/MappingByCode/ExpliticMappingTests/DynamicComponentMappingTests.cs Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/ExplicitlyDeclaredModel.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/ExplicitlyDeclaredModel.cs 2011-04-22 02:55:49 UTC (rev 5735) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/ExplicitlyDeclaredModel.cs 2011-04-22 14:14:26 UTC (rev 5736) @@ -21,6 +21,8 @@ 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>(); @@ -135,6 +137,11 @@ get { return properties; } } + public IEnumerable<MemberInfo> DynamicComponents + { + get { return dynamicComponents; } + } + public IEnumerable<MemberInfo> PersistentMembers { get { return persistentMembers; } @@ -404,6 +411,13 @@ 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; @@ -538,6 +552,18 @@ return properties.Contains(member); } + public bool IsDynamicComponent(MemberInfo member) + { + return dynamicComponents.Contains(member); + } + + public System.Type GetDynamicComponentTemplate(MemberInfo member) + { + System.Type template; + dynamicComponentTemplates.TryGetValue(member, out template); + return template ?? typeof(object); + } + public IEnumerable<string> GetPropertiesSplits(System.Type type) { return GetSplitGroupsFor(type); Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/FakeModelExplicitDeclarationsHolder.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/FakeModelExplicitDeclarationsHolder.cs 2011-04-22 02:55:49 UTC (rev 5735) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/FakeModelExplicitDeclarationsHolder.cs 2011-04-22 14:14:26 UTC (rev 5736) @@ -21,6 +21,7 @@ private readonly IEnumerable<MemberInfo> oneToOneRelations = Enumerable.Empty<MemberInfo>(); private readonly IEnumerable<MemberInfo> poids = Enumerable.Empty<MemberInfo>(); private readonly IEnumerable<MemberInfo> properties = Enumerable.Empty<MemberInfo>(); + private readonly IEnumerable<MemberInfo> dynamicComponents = Enumerable.Empty<MemberInfo>(); private readonly IEnumerable<MemberInfo> persistentMembers = new HashSet<MemberInfo>(); private readonly IEnumerable<System.Type> rootEntities = Enumerable.Empty<System.Type>(); private readonly IEnumerable<MemberInfo> sets = Enumerable.Empty<MemberInfo>(); @@ -138,6 +139,11 @@ get { return properties; } } + public IEnumerable<MemberInfo> DynamicComponents + { + get { return dynamicComponents; } + } + public IEnumerable<MemberInfo> PersistentMembers { get { return persistentMembers; } @@ -158,6 +164,11 @@ return null; } + public System.Type GetDynamicComponentTemplate(MemberInfo member) + { + return typeof(object); + } + public void AddAsRootEntity(System.Type type) {} public void AddAsComponent(System.Type type) {} @@ -201,7 +212,7 @@ public void AddAsProperty(MemberInfo member) {} public void AddAsPersistentMember(MemberInfo member){} public void AddAsPropertySplit(SplitDefinition definition) {} - + public void AddAsDynamicComponent(MemberInfo member, System.Type componentTemplate) {} #endregion } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/IModelExplicitDeclarationsHolder.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/IModelExplicitDeclarationsHolder.cs 2011-04-22 02:55:49 UTC (rev 5735) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/IModelExplicitDeclarationsHolder.cs 2011-04-22 14:14:26 UTC (rev 5736) @@ -42,11 +42,13 @@ IEnumerable<MemberInfo> Arrays { get; } IEnumerable<MemberInfo> Dictionaries { get; } IEnumerable<MemberInfo> Properties { get; } + IEnumerable<MemberInfo> DynamicComponents { get; } IEnumerable<MemberInfo> PersistentMembers { get; } IEnumerable<SplitDefinition> SplitDefinitions { get; } IEnumerable<string> GetSplitGroupsFor(System.Type type); string GetSplitGroupFor(MemberInfo member); + System.Type GetDynamicComponentTemplate(MemberInfo member); void AddAsRootEntity(System.Type type); void AddAsComponent(System.Type type); @@ -73,5 +75,6 @@ void AddAsProperty(MemberInfo member); void AddAsPersistentMember(MemberInfo member); void AddAsPropertySplit(SplitDefinition definition); + void AddAsDynamicComponent(MemberInfo member, System.Type componentTemplate); } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/IModelInspector.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/IModelInspector.cs 2011-04-22 02:55:49 UTC (rev 5735) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/IModelInspector.cs 2011-04-22 14:14:26 UTC (rev 5736) @@ -33,6 +33,8 @@ bool IsArray(MemberInfo role); bool IsDictionary(MemberInfo role); bool IsProperty(MemberInfo member); + bool IsDynamicComponent(MemberInfo member); + System.Type GetDynamicComponentTemplate(MemberInfo member); IEnumerable<string> GetPropertiesSplits(System.Type type); } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersHolder.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersHolder.cs 2011-04-22 02:55:49 UTC (rev 5735) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersHolder.cs 2011-04-22 14:14:26 UTC (rev 5736) @@ -33,6 +33,9 @@ private readonly Dictionary<PropertyPath, List<Action<IComponentAttributesMapper>>> componentPropertyCustomizers = new Dictionary<PropertyPath, List<Action<IComponentAttributesMapper>>>(); + private readonly Dictionary<PropertyPath, List<Action<IDynamicComponentAttributesMapper>>> dynamicComponentCustomizers = + new Dictionary<PropertyPath, List<Action<IDynamicComponentAttributesMapper>>>(); + private readonly Dictionary<System.Type, List<Action<IJoinedSubclassAttributesMapper>>> joinedClassCustomizers = new Dictionary<System.Type, List<Action<IJoinedSubclassAttributesMapper>>>(); @@ -159,6 +162,11 @@ AddCustomizer(componentPropertyCustomizers, member, propertyCustomizer); } + public void AddCustomizer(PropertyPath member, Action<IDynamicComponentAttributesMapper> propertyCustomizer) + { + AddCustomizer(dynamicComponentCustomizers, member, propertyCustomizer); + } + public void AddCustomizer(PropertyPath member, Action<IManyToManyMapper> collectionRelationManyToManyCustomizer) { AddCustomizer(collectionRelationManyToManyCustomizers, member, collectionRelationManyToManyCustomizer); @@ -274,6 +282,11 @@ InvokeCustomizers(componentPropertyCustomizers, member, mapper); } + public void InvokeCustomizers(PropertyPath member, IDynamicComponentAttributesMapper mapper) + { + InvokeCustomizers(dynamicComponentCustomizers, member, mapper); + } + public void InvokeCustomizers(PropertyPath member, IManyToManyMapper mapper) { InvokeCustomizers(collectionRelationManyToManyCustomizers, member, mapper); Added: trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/DynamicComponentCustomizer.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/DynamicComponentCustomizer.cs (rev 0) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/DynamicComponentCustomizer.cs 2011-04-22 14:14:26 UTC (rev 5736) @@ -0,0 +1,50 @@ +using System; + +namespace NHibernate.Mapping.ByCode.Impl.CustomizersImpl +{ + public class DynamicComponentCustomizer<TComponent> : PropertyContainerCustomizer<TComponent>, IDynamicComponentMapper<TComponent> where TComponent : class + { + public DynamicComponentCustomizer(IModelExplicitDeclarationsHolder explicitDeclarationsHolder, ICustomizersHolder customizersHolder, PropertyPath propertyPath) + : base(explicitDeclarationsHolder, customizersHolder, propertyPath) + { + if (propertyPath == null) + { + throw new ArgumentNullException("propertyPath"); + } + if (explicitDeclarationsHolder == null) + { + throw new ArgumentNullException("explicitDeclarationsHolder"); + } + explicitDeclarationsHolder.AddAsDynamicComponent(propertyPath.LocalMember, typeof(TComponent)); + } + + #region IDynamicComponentMapper<TComponent> Members + + public void Access(Accessor accessor) + { + throw new NotImplementedException(); + } + + public void Access(System.Type accessorType) + { + throw new NotImplementedException(); + } + + public void OptimisticLock(bool takeInConsiderationForOptimisticLock) + { + throw new NotImplementedException(); + } + + public void Update(bool consideredInUpdateQuery) + { + throw new NotImplementedException(); + } + + public void Insert(bool consideredInInsertQuery) + { + throw new NotImplementedException(); + } + + #endregion + } +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/PropertyContainerCustomizer.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/PropertyContainerCustomizer.cs 2011-04-22 02:55:49 UTC (rev 5735) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/PropertyContainerCustomizer.cs 2011-04-22 14:14:26 UTC (rev 5736) @@ -83,9 +83,17 @@ TComponent dynamicComponentTemplate, Action<IDynamicComponentMapper<TComponent>> mapping) where TComponent : class { - throw new NotImplementedException(); + RegisterDynamicComponentMapping(property, mapping); } + protected virtual void RegisterDynamicComponentMapping<TComponent>(Expression<Func<TEntity, IDictionary>> property, Action<IDynamicComponentMapper<TComponent>> mapping) where TComponent : class + { + MemberInfo member = TypeExtensions.DecodeMemberAccessExpression(property); + mapping(new DynamicComponentCustomizer<TComponent>(explicitDeclarationsHolder, CustomizersHolder, new PropertyPath(PropertyPath, member))); + MemberInfo memberOf = TypeExtensions.DecodeMemberAccessExpressionOf(property); + mapping(new DynamicComponentCustomizer<TComponent>(explicitDeclarationsHolder, CustomizersHolder, new PropertyPath(PropertyPath, memberOf))); + } + public void ManyToOne<TProperty>(Expression<Func<TEntity, TProperty>> property, Action<IManyToOneMapper> mapping) where TProperty : class { Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/DefaultCandidatePersistentMembersProvider.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/DefaultCandidatePersistentMembersProvider.cs 2011-04-22 02:55:49 UTC (rev 5735) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/DefaultCandidatePersistentMembersProvider.cs 2011-04-22 14:14:26 UTC (rev 5736) @@ -23,7 +23,7 @@ public IEnumerable<MemberInfo> GetRootEntityMembers(System.Type entityClass) { - return GetCandidatePersistentProperties(entityClass, RootClassPropertiesBindingFlags).Concat(entityClass.GetFields(ClassFieldsBindingFlags)); + return GetCandidatePersistentProperties(entityClass, RootClassPropertiesBindingFlags).Concat(GetUserDeclaredFields(entityClass).Cast<MemberInfo>()); } public IEnumerable<MemberInfo> GetSubEntityMembers(System.Type entityClass, System.Type entitySuperclass) @@ -35,17 +35,23 @@ { IEnumerable<MemberInfo> propertiesOfSubclass = GetCandidatePersistentProperties(entityClass, flattenHierarchyBindingFlag); IEnumerable<MemberInfo> propertiesOfBaseClass = GetCandidatePersistentProperties(entitySuperclass, flattenHierarchyBindingFlag); - return propertiesOfSubclass.Except(propertiesOfBaseClass, new PropertyNameEqualityComparer()).Concat(entityClass.GetFields(ClassFieldsBindingFlags)); + return propertiesOfSubclass.Except(propertiesOfBaseClass, new PropertyNameEqualityComparer()).Concat(GetUserDeclaredFields(entityClass).Cast<MemberInfo>()); } else { - return GetCandidatePersistentProperties(entityClass, SubClassPropertiesBindingFlags).Concat(entityClass.GetFields(ClassFieldsBindingFlags)); + return GetCandidatePersistentProperties(entityClass, SubClassPropertiesBindingFlags).Concat(GetUserDeclaredFields(entityClass).Cast<MemberInfo>()); } } + protected IEnumerable<FieldInfo> GetUserDeclaredFields(System.Type type) + { + // can't find another way to exclude fields generated by the compiler (for both auto-properties and anonymous-types) + return type.GetFields(ClassFieldsBindingFlags).Where(x=> !x.Name.StartsWith("<")); + } + public IEnumerable<MemberInfo> GetComponentMembers(System.Type componentClass) { - return GetCandidatePersistentProperties(componentClass, ComponentPropertiesBindingFlags).Concat(componentClass.GetFields(ClassFieldsBindingFlags)); + return GetCandidatePersistentProperties(componentClass, ComponentPropertiesBindingFlags).Concat(GetUserDeclaredFields(componentClass).Cast<MemberInfo>()); } #endregion @@ -55,7 +61,7 @@ System.Type analizing = type; while (analizing != null && analizing != typeof (object)) { - foreach (FieldInfo fieldInfo in analizing.GetFields(ClassFieldsBindingFlags)) + foreach (FieldInfo fieldInfo in GetUserDeclaredFields(analizing)) { yield return fieldInfo; } Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/ExplicitDeclarationsHolder.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/ExplicitDeclarationsHolder.cs 2011-04-22 02:55:49 UTC (rev 5735) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/ExplicitDeclarationsHolder.cs 2011-04-22 14:14:26 UTC (rev 5736) @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Linq; using System.Reflection; @@ -21,6 +20,8 @@ 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>(); @@ -132,6 +133,11 @@ get { return properties; } } + public IEnumerable<MemberInfo> DynamicComponents + { + get { return dynamicComponents; } + } + public IEnumerable<MemberInfo> PersistentMembers { get { return persistentMembers; } @@ -152,6 +158,13 @@ return null; } + public System.Type GetDynamicComponentTemplate(MemberInfo member) + { + System.Type template; + dynamicComponentTemplates.TryGetValue(member, out template); + return template ?? typeof(object); + } + public void AddAsRootEntity(System.Type type) { rootEntities.Add(type); @@ -262,6 +275,12 @@ splitDefinitions.Add(definition); } + public void AddAsDynamicComponent(MemberInfo member, System.Type componentTemplate) + { + dynamicComponents.Add(member); + dynamicComponentTemplates[member] = componentTemplate; + } + #endregion } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/ICustomizersHolder.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/ICustomizersHolder.cs 2011-04-22 02:55:49 UTC (rev 5735) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/ICustomizersHolder.cs 2011-04-22 14:14:26 UTC (rev 5736) @@ -24,6 +24,7 @@ void AddCustomizer(PropertyPath member, Action<IIdBagPropertiesMapper> propertyCustomizer); void AddCustomizer(PropertyPath member, Action<ICollectionPropertiesMapper> propertyCustomizer); void AddCustomizer(PropertyPath member, Action<IComponentAttributesMapper> propertyCustomizer); + void AddCustomizer(PropertyPath member, Action<IDynamicComponentAttributesMapper> propertyCustomizer); void InvokeCustomizers(System.Type type, IClassMapper mapper); void InvokeCustomizers(System.Type type, ISubclassMapper mapper); @@ -43,6 +44,7 @@ void InvokeCustomizers(PropertyPath member, IMapPropertiesMapper mapper); void InvokeCustomizers(PropertyPath member, IIdBagPropertiesMapper mapper); void InvokeCustomizers(PropertyPath member, IComponentAttributesMapper mapper); + void InvokeCustomizers(PropertyPath member, IDynamicComponentAttributesMapper mapper); #region Collection Element relations invokers Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/ModelExplicitDeclarationsHolderExtensions.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/ModelExplicitDeclarationsHolderExtensions.cs 2011-04-22 02:55:49 UTC (rev 5735) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/ModelExplicitDeclarationsHolderExtensions.cs 2011-04-22 14:14:26 UTC (rev 5736) @@ -36,6 +36,11 @@ System.Array.ForEach(source.Properties.ToArray(), destination.AddAsProperty); System.Array.ForEach(source.PersistentMembers.ToArray(), destination.AddAsPersistentMember); System.Array.ForEach(source.SplitDefinitions.ToArray(), destination.AddAsPropertySplit); + foreach (var dynamicComponent in source.DynamicComponents) + { + var template = source.GetDynamicComponentTemplate(dynamicComponent); + destination.AddAsDynamicComponent(dynamicComponent, template); + } } } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/ModelMapper.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/ModelMapper.cs 2011-04-22 02:55:49 UTC (rev 5735) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/ModelMapper.cs 2011-04-22 14:14:26 UTC (rev 5736) @@ -903,6 +903,10 @@ { MapOneToOne(member, memberPath, propertiesContainer); } + else if (modelInspector.IsDynamicComponent(property)) + { + MapDynamicComponent(member, memberPath, propertyType, propertiesContainer); + } else if (modelInspector.IsSet(property)) { MapSet(member, memberPath, propertyType, propertiesContainer, propertiesContainerType); @@ -938,6 +942,19 @@ } } + private void MapDynamicComponent(MemberInfo member, PropertyPath memberPath, System.Type propertyType, IPropertyContainerMapper propertiesContainer) + { + propertiesContainer.Component(member, (IDynamicComponentMapper componentMapper) => + { + System.Type componentType = modelInspector.GetDynamicComponentTemplate(member); + IEnumerable<MemberInfo> persistentProperties = membersProvider.GetComponentMembers(componentType); + + ForEachMemberPath(member, memberPath, pp => customizerHolder.InvokeCustomizers(pp, componentMapper)); + + MapProperties(propertyType, persistentProperties, componentMapper, memberPath); + }); + } + private void MapAny(MemberInfo member, PropertyPath memberPath, IBasePlainPropertyContainerMapper propertiesContainer) { propertiesContainer.Any(member, typeof (int), anyMapper => Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/SimpleModelInspector.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/SimpleModelInspector.cs 2011-04-22 02:55:49 UTC (rev 5735) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/SimpleModelInspector.cs 2011-04-22 14:14:26 UTC (rev 5736) @@ -27,6 +27,7 @@ private Func<MemberInfo, bool, bool> isVersion = (m, declared) => declared; private Func<MemberInfo, bool, bool> isProperty = (m, declared) => declared; + private Func<MemberInfo, bool, bool> isDynamicComponent = (m, declared) => declared; private Func<MemberInfo, bool, bool> isAny = (m, declared) => declared; private Func<MemberInfo, bool, bool> isManyToMany = (m, declared) => declared; private Func<MemberInfo, bool, bool> isManyToOne; @@ -341,6 +342,11 @@ get { return declaredModel.SplitDefinitions; } } + IEnumerable<MemberInfo> IModelExplicitDeclarationsHolder.DynamicComponents + { + get { return declaredModel.DynamicComponents; } + } + IEnumerable<string> IModelExplicitDeclarationsHolder.GetSplitGroupsFor(System.Type type) { return declaredModel.GetSplitGroupsFor(type); @@ -461,6 +467,11 @@ declaredModel.AddAsPropertySplit(definition); } + void IModelExplicitDeclarationsHolder.AddAsDynamicComponent(MemberInfo member, System.Type componentTemplate) + { + declaredModel.AddAsDynamicComponent(member, componentTemplate); + } + #endregion #region Implementation of IModelInspector @@ -603,6 +614,21 @@ return isProperty(member, declaredResult); } + bool IModelInspector.IsDynamicComponent(MemberInfo member) + { + bool declaredResult = declaredModel.IsDynamicComponent(member); + return isDynamicComponent(member, declaredResult); + } + + System.Type IModelInspector.GetDynamicComponentTemplate(MemberInfo member) + { + return declaredModel.GetDynamicComponentTemplate(member); + } + System.Type IModelExplicitDeclarationsHolder.GetDynamicComponentTemplate(MemberInfo member) + { + return declaredModel.GetDynamicComponentTemplate(member); + } + IEnumerable<string> IModelInspector.GetPropertiesSplits(System.Type type) { IEnumerable<string> declaredResult = declaredModel.GetPropertiesSplits(type); @@ -826,5 +852,14 @@ } isTablePerClassSplit = match; } + + public void IsDynamicComponent(Func<MemberInfo, bool, bool> match) + { + if (match == null) + { + return; + } + isDynamicComponent = match; + } } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj =================================================================== --- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2011-04-22 02:55:49 UTC (rev 5735) +++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2011-04-22 14:14:26 UTC (rev 5736) @@ -295,6 +295,7 @@ <Compile Include="Mapping\ByCode\Conformist\SubclassMapping.cs" /> <Compile Include="Mapping\ByCode\Conformist\UnionSubclassMapping.cs" /> <Compile Include="Mapping\ByCode\IDynamicComponentAttributesMapper.cs" /> + <Compile Include="Mapping\ByCode\Impl\CustomizersImpl\DynamicComponentCustomizer.cs" /> <Compile Include="Mapping\ByCode\Impl\DynamicComponentMapper.cs" /> <Compile Include="Mapping\ByCode\PropertyToField.cs" /> <Compile Include="Mapping\ByCode\SimpleModelInspector.cs" /> Added: trunk/nhibernate/src/NHibernate.Test/MappingByCode/ExpliticMappingTests/DynamicComponentMappingTests.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/MappingByCode/ExpliticMappingTests/DynamicComponentMappingTests.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/MappingByCode/ExpliticMappingTests/DynamicComponentMappingTests.cs 2011-04-22 14:14:26 UTC (rev 5736) @@ -0,0 +1,36 @@ +using System; +using System.Collections; +using System.Linq; +using NHibernate.Cfg.MappingSchema; +using NHibernate.Mapping.ByCode; +using NUnit.Framework; +using SharpTestsEx; + +namespace NHibernate.Test.MappingByCode.ExpliticMappingTests +{ + public class DynamicComponentMappingTests + { + private class Person + { + public int Id { get; set; } + public IDictionary Info { get; set; } + } + + [Test] + public void WhenMapDynCompoThenMapItAndItsProperties() + { + var mapper = new ModelMapper(); + mapper.Class<Person>(map => + { + map.Id(x => x.Id, idmap => { }); + map.Component(x => x.Info, new { MyInt = 5, MyDate = DateTime.Now }, z => { }); + }); + + var hbmMapping = mapper.CompileMappingFor(new[] { typeof(Person) }); + var hbmClass = hbmMapping.RootClasses[0]; + var hbmDynamicComponent = hbmClass.Properties.OfType<HbmDynamicComponent>().SingleOrDefault(); + hbmDynamicComponent.Should().Not.Be.Null(); + hbmDynamicComponent.Properties.Select(x=> x.Name).Should().Have.SameValuesAs("MyInt", "MyDate"); + } + } +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate.Test/MappingByCode/ModelExplicitDeclarationsHolderMergeTest.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/MappingByCode/ModelExplicitDeclarationsHolderMergeTest.cs 2011-04-22 02:55:49 UTC (rev 5735) +++ trunk/nhibernate/src/NHibernate.Test/MappingByCode/ModelExplicitDeclarationsHolderMergeTest.cs 2011-04-22 14:14:26 UTC (rev 5736) @@ -259,6 +259,18 @@ destination.RootEntities.Should().Have.Count.EqualTo(1); } + [Test] + public void MergeDynamicComponents() + { + var destination = new ExplicitDeclarationsHolder(); + var source = new ExplicitDeclarationsHolder(); + source.AddAsDynamicComponent(property, typeof(MyClass)); + + destination.Merge(source); + destination.DynamicComponents.Should().Have.Count.EqualTo(1); + destination.GetDynamicComponentTemplate(property).Should().Be(typeof(MyClass)); + } + #region Nested type: MyClass private class MyClass Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-04-22 02:55:49 UTC (rev 5735) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-04-22 14:14:26 UTC (rev 5736) @@ -536,6 +536,7 @@ <Compile Include="MappingByCode\ExpliticMappingTests\ConformistMappingRegistrationTests\ModelMapperAddMappingByTypeTests.cs" /> <Compile Include="MappingByCode\ExpliticMappingTests\ConformistMappingRegistrationTests\SubclassMappingRegistration.cs" /> <Compile Include="MappingByCode\ExpliticMappingTests\ConformistMappingRegistrationTests\UnionSubclassMappingRegistrationTest.cs" /> + <Compile Include="MappingByCode\ExpliticMappingTests\DynamicComponentMappingTests.cs" /> <Compile Include="MappingByCode\ExpliticMappingTests\IdBagMappingTest.cs" /> <Compile Include="MappingByCode\ExpliticMappingTests\MappingOfPrivateMembersOnRootEntity.cs" /> <Compile Include="MappingByCode\ExpliticMappingTests\NaturalIdTests.cs" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |