From: <fab...@us...> - 2011-04-29 16:52:02
|
Revision: 5788 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5788&view=rev Author: fabiomaulo Date: 2011-04-29 16:51:56 +0000 (Fri, 29 Apr 2011) Log Message: ----------- SimpleModelInspector managing polymorphic registration Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Mapping/ByCode/SimpleModelInspector.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/TypeExtensions.cs trunk/nhibernate/src/NHibernate.Test/MappingByCode/TypeExtensionsTests/TypeExtensionsTest.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/MappingByCode/MixAutomapping/PolymorphicPropertiesMapping.cs Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/SimpleModelInspector.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/SimpleModelInspector.cs 2011-04-28 22:49:42 UTC (rev 5787) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/SimpleModelInspector.cs 2011-04-29 16:51:56 UTC (rev 5788) @@ -530,108 +530,108 @@ bool IModelInspector.IsOneToOne(MemberInfo member) { - bool declaredResult = declaredModel.IsOneToOne(member); + bool declaredResult = DeclaredPolymorphicMatch(member, m => declaredModel.IsOneToOne(m)); return isOneToOne(member, declaredResult); } bool IModelInspector.IsManyToOne(MemberInfo member) { - bool declaredResult = declaredModel.IsManyToOne(member); + bool declaredResult = DeclaredPolymorphicMatch(member, m => declaredModel.IsManyToOne(m)); return isManyToOne(member, declaredResult); } bool IModelInspector.IsManyToMany(MemberInfo member) { - bool declaredResult = declaredModel.IsManyToMany(member); + bool declaredResult = DeclaredPolymorphicMatch(member, m => declaredModel.IsManyToMany(m)); return isManyToMany(member, declaredResult); } bool IModelInspector.IsOneToMany(MemberInfo member) { - bool declaredResult = declaredModel.IsOneToMany(member); + bool declaredResult = DeclaredPolymorphicMatch(member, m => declaredModel.IsOneToMany(m)); return isOneToMany(member, declaredResult); } bool IModelInspector.IsAny(MemberInfo member) { - bool declaredResult = declaredModel.IsAny(member); + bool declaredResult = DeclaredPolymorphicMatch(member, m => declaredModel.IsAny(m)); return isAny(member, declaredResult); } bool IModelInspector.IsPersistentId(MemberInfo member) { - bool declaredResult = declaredModel.IsPersistentId(member); + bool declaredResult = DeclaredPolymorphicMatch(member, m => declaredModel.IsPersistentId(m)); return isPersistentId(member, declaredResult); } bool IModelInspector.IsMemberOfComposedId(MemberInfo member) { - return declaredModel.IsPersistentId(member); + return declaredModel.IsMemberOfComposedId(member); } bool IModelInspector.IsVersion(MemberInfo member) { - bool declaredResult = declaredModel.IsVersion(member); + bool declaredResult = DeclaredPolymorphicMatch(member, m => declaredModel.IsVersion(m)); return isVersion(member, declaredResult); } bool IModelInspector.IsMemberOfNaturalId(MemberInfo member) { - bool declaredResult = declaredModel.IsMemberOfNaturalId(member); + bool declaredResult = DeclaredPolymorphicMatch(member, m => declaredModel.IsMemberOfNaturalId(m)); return isMemberOfNaturalId(member, declaredResult); } bool IModelInspector.IsPersistentProperty(MemberInfo member) { - bool declaredResult = declaredModel.IsPersistentProperty(member); + bool declaredResult = DeclaredPolymorphicMatch(member, m => declaredModel.IsPersistentProperty(m)); return isPersistentProperty(member, declaredResult); } bool IModelInspector.IsSet(MemberInfo role) { - bool declaredResult = declaredModel.IsSet(role); + bool declaredResult = DeclaredPolymorphicMatch(role, m => declaredModel.IsSet(m)); return isSet(role, declaredResult); } bool IModelInspector.IsBag(MemberInfo role) { - bool declaredResult = declaredModel.IsBag(role); + bool declaredResult = DeclaredPolymorphicMatch(role, m => declaredModel.IsBag(m)); return isBag(role, declaredResult); } bool IModelInspector.IsIdBag(MemberInfo role) { - bool declaredResult = declaredModel.IsIdBag(role); + bool declaredResult = DeclaredPolymorphicMatch(role, m => declaredModel.IsIdBag(m)); return isIdBag(role, declaredResult); } bool IModelInspector.IsList(MemberInfo role) { - bool declaredResult = declaredModel.IsList(role); + bool declaredResult = DeclaredPolymorphicMatch(role, m => declaredModel.IsList(m)); return isList(role, declaredResult); } bool IModelInspector.IsArray(MemberInfo role) { - bool declaredResult = declaredModel.IsArray(role); + bool declaredResult = DeclaredPolymorphicMatch(role, m => declaredModel.IsArray(m)); return isArray(role, declaredResult); } bool IModelInspector.IsDictionary(MemberInfo role) { - bool declaredResult = declaredModel.IsDictionary(role); + bool declaredResult = DeclaredPolymorphicMatch(role, m => declaredModel.IsDictionary(m)); return isDictionary(role, declaredResult); } bool IModelInspector.IsProperty(MemberInfo member) { - bool declaredResult = declaredModel.IsProperty(member); + bool declaredResult = DeclaredPolymorphicMatch(member, m => declaredModel.IsProperty(m)); return isProperty(member, declaredResult); } bool IModelInspector.IsDynamicComponent(MemberInfo member) { - bool declaredResult = declaredModel.IsDynamicComponent(member); + bool declaredResult = DeclaredPolymorphicMatch(member, m => declaredModel.IsDynamicComponent(m)); return isDynamicComponent(member, declaredResult); } @@ -652,6 +652,13 @@ #endregion + protected virtual bool DeclaredPolymorphicMatch(MemberInfo member, Func<MemberInfo, bool> declaredMatch) + { + return declaredMatch(member) + || member.GetMemberFromDeclaringClasses().Any(declaredMatch) + || member.GetPropertyFromInterfaces().Any(declaredMatch); + } + public void IsRootEntity(Func<System.Type, bool, bool> match) { if (match == null) Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/TypeExtensions.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/TypeExtensions.cs 2011-04-28 22:49:42 UTC (rev 5787) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/TypeExtensions.cs 2011-04-29 16:51:56 UTC (rev 5788) @@ -170,9 +170,36 @@ { return source; } - return source.DeclaringType.GetProperty(source.Name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly); + if (source is PropertyInfo) + { + return source.DeclaringType.GetProperty(source.Name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly); + } + if (source is FieldInfo) + { + return source.DeclaringType.GetField(source.Name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly); + } + return null; } + public static IEnumerable<MemberInfo> GetMemberFromDeclaringClasses(this MemberInfo source) + { + if (source == null) + { + throw new ArgumentNullException("source"); + } + if (source is PropertyInfo) + { + var reflectedType = source.ReflectedType; + var memberType = source.GetPropertyOrFieldType(); + return reflectedType.GetPropertiesOfHierarchy().Cast<PropertyInfo>().Where(x => source.Name.Equals(x.Name) && memberType.Equals(x.PropertyType)).Cast<MemberInfo>(); + } + if (source is FieldInfo) + { + return new[] { source.GetMemberFromDeclaringType() }; + } + return Enumerable.Empty<MemberInfo>(); + } + public static IEnumerable<MemberInfo> GetPropertyFromInterfaces(this MemberInfo source) { if (source == null) Added: trunk/nhibernate/src/NHibernate.Test/MappingByCode/MixAutomapping/PolymorphicPropertiesMapping.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/MappingByCode/MixAutomapping/PolymorphicPropertiesMapping.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/MappingByCode/MixAutomapping/PolymorphicPropertiesMapping.cs 2011-04-29 16:51:56 UTC (rev 5788) @@ -0,0 +1,99 @@ +using System; +using System.Reflection; +using NHibernate.Mapping.ByCode; +using NUnit.Framework; +using SharpTestsEx; + +namespace NHibernate.Test.MappingByCode.MixAutomapping +{ + public class PolymorphicPropertiesMapping + { + const BindingFlags RootClassPropertiesBindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy; + + private interface IBaseEntity + { + int Id { get; } + } + + private class BaseEntity : IBaseEntity + { + public int Id { get; protected set; } + public DateTime LastChange { get { return DateTime.Now; } } + } + + private interface IProduct : IBaseEntity + { + string Description { get;} + } + + private abstract class BaseProduct : BaseEntity, IProduct + { + public abstract string Description { get; } + } + + private class Product : BaseProduct + { + public override string Description + { + get { return "blah"; } + } + } + + [Test] + public void WhenMapIdThroughBaseInterfaceThenFindIt() + { + var inspector = (IModelInspector)new SimpleModelInspector(); + var mapper = new ModelMapper(inspector); + mapper.Class<IBaseEntity>( + map => + { + map.Id(x => x.Id, idmap => { }); + }); + inspector.IsPersistentId(typeof(Product).GetProperty("Id", RootClassPropertiesBindingFlags)).Should().Be.True(); + } + + [Test] + public void WhenMapPropertyThroughBaseConcreteClassThenFindIt() + { + var inspector = (IModelInspector)new SimpleModelInspector(); + var mapper = new ModelMapper(inspector); + + mapper.Class<BaseEntity>(map => map.Property(x => x.LastChange)); + + inspector.IsPersistentProperty(typeof(Product).GetProperty("LastChange", RootClassPropertiesBindingFlags)).Should().Be.True(); + } + + [Test] + public void WhenMapPropertyThroughBaseInterfaceThenFindIt() + { + var inspector = (IModelInspector)new SimpleModelInspector(); + var mapper = new ModelMapper(inspector); + + mapper.Class<IProduct>(map => map.Property(x => x.Description)); + + inspector.IsPersistentProperty(typeof(Product).GetProperty("Description", RootClassPropertiesBindingFlags)).Should().Be.True(); + } + + [Test] + public void WhenMapPropertyThroughBaseAbstractClassThenFindIt() + { + var inspector = (IModelInspector)new SimpleModelInspector(); + var mapper = new ModelMapper(inspector); + + mapper.Class<BaseProduct>(map => map.Property(x => x.Description)); + + inspector.IsPersistentProperty(typeof(Product).GetProperty("Description", RootClassPropertiesBindingFlags)).Should().Be.True(); + } + + [Test] + public void WhenMapPropertyThroughClassThenFindIt() + { + var inspector = (IModelInspector)new SimpleModelInspector(); + var mapper = new ModelMapper(inspector); + + mapper.Class<Product>(map => map.Property(x => x.Description)); + + inspector.IsPersistentProperty(typeof(Product).GetProperty("Description", RootClassPropertiesBindingFlags)).Should().Be.True(); + } + } +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate.Test/MappingByCode/TypeExtensionsTests/TypeExtensionsTest.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/MappingByCode/TypeExtensionsTests/TypeExtensionsTest.cs 2011-04-28 22:49:42 UTC (rev 5787) +++ trunk/nhibernate/src/NHibernate.Test/MappingByCode/TypeExtensionsTests/TypeExtensionsTest.cs 2011-04-29 16:51:56 UTC (rev 5788) @@ -2,6 +2,7 @@ using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Linq; using System.Reflection; using NHibernate.Mapping.ByCode; using NUnit.Framework; @@ -203,5 +204,41 @@ typeof(MyBaseClass).HasPublicPropertyOf(typeof(string), x => false).Should().Be.False(); typeof(MyBaseClass).HasPublicPropertyOf(typeof(string), x => true).Should().Be.True(); } + + private abstract class MyAbstract + { + protected int aField; + public abstract string Description { get; } + } + + private class MyConcrete : MyAbstract + { + public override string Description + { + get { return "blah"; } + } + } + + [Test] + public void GetMemberFromDeclaringClasses_WhenPropertyThenFindAbstract() + { + var member = typeof(MyConcrete).GetProperty("Description", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy); + var found = member.GetMemberFromDeclaringClasses().ToList(); + found.Count.Should().Be(2); + var concreteMember = For<MyConcrete>.Property(x => x.Description).GetMemberFromReflectedType(typeof(MyConcrete)); + var abstractMember = For<MyAbstract>.Property(x => x.Description); + found.Should().Have.SameValuesAs(concreteMember, abstractMember); + } + + [Test] + public void GetMemberFromDeclaringClasses_WhenFieldThenFindAbstract() + { + var member = typeof(MyConcrete).GetField("aField", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy); + var found = member.GetMemberFromDeclaringClasses().ToList(); + found.Count.Should().Be(1); + var foundMember = found.Single(); + foundMember.DeclaringType.Should().Be(typeof(MyAbstract)); + foundMember.ReflectedType.Should().Be(typeof(MyAbstract)); + } } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-04-28 22:49:42 UTC (rev 5787) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-04-29 16:51:56 UTC (rev 5788) @@ -592,6 +592,7 @@ <Compile Include="MappingByCode\MixAutomapping\ManyToOneTest.cs" /> <Compile Include="MappingByCode\MixAutomapping\OneToManyTests.cs" /> <Compile Include="MappingByCode\MixAutomapping\PoidTests.cs" /> + <Compile Include="MappingByCode\MixAutomapping\PolymorphicPropertiesMapping.cs" /> <Compile Include="MappingByCode\MixAutomapping\PropertiesExclusionTests.cs" /> <Compile Include="MappingByCode\MixAutomapping\RootEntityTests.cs" /> <Compile Include="MappingByCode\MixAutomapping\SetCollectionTests.cs" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |