From: <fab...@us...> - 2011-04-13 20:17:03
|
Revision: 5693 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5693&view=rev Author: fabiomaulo Date: 2011-04-13 20:16:57 +0000 (Wed, 13 Apr 2011) Log Message: ----------- ConventionModelMapper safe property accessor Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Mapping/ByCode/ConventionModelMapper.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/MappingByCode/ConventionModelMapperTests/PropertyToFieldAccessorTest.cs Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/ConventionModelMapper.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/ConventionModelMapper.cs 2011-04-13 19:03:48 UTC (rev 5692) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/ConventionModelMapper.cs 2011-04-13 20:16:57 UTC (rev 5693) @@ -17,8 +17,42 @@ { BeforeMapClass += NoPoidGuid; BeforeMapClass += NoSetterPoidToField; + + BeforeMapProperty += MemberToFieldAccessor; + BeforeMapBag += MemberToFieldAccessor; + BeforeMapSet += MemberToFieldAccessor; + BeforeMapMap += MemberToFieldAccessor; + BeforeMapList += MemberToFieldAccessor; + + BeforeMapManyToOne += MemberToFieldAccessor; + BeforeMapOneToOne += MemberToFieldAccessor; + BeforeMapAny += MemberToFieldAccessor; } + void MemberToFieldAccessor(IModelInspector modelInspector, PropertyPath member, IAccessorPropertyMapper propertyCustomizer) + { + if (MatchPropertyToField(member.LocalMember)) + { + propertyCustomizer.Access(Accessor.Field); + } + } + + protected bool MatchPropertyToField(MemberInfo subject) + { + var property = subject as PropertyInfo; + if (property == null) + { + return false; + } + var fieldInfo = PropertyToField.GetBackFieldInfo(property); + if (fieldInfo != null) + { + return fieldInfo.FieldType != property.PropertyType; + } + + return false; + } + protected virtual void NoSetterPoidToField(IModelInspector modelInspector, System.Type type, IClassAttributesMapper classCustomizer) { MemberInfo poidPropertyOrField = MembersProvider.GetEntityMembersForPoid(type).FirstOrDefault(modelInspector.IsPersistentId); @@ -28,7 +62,7 @@ } } - public bool MatchNoSetterProperty(MemberInfo subject) + protected bool MatchNoSetterProperty(MemberInfo subject) { var property = subject as PropertyInfo; if (property == null || property.CanWrite || !property.CanRead) Added: trunk/nhibernate/src/NHibernate.Test/MappingByCode/ConventionModelMapperTests/PropertyToFieldAccessorTest.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/MappingByCode/ConventionModelMapperTests/PropertyToFieldAccessorTest.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/MappingByCode/ConventionModelMapperTests/PropertyToFieldAccessorTest.cs 2011-04-13 20:16:57 UTC (rev 5693) @@ -0,0 +1,131 @@ +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using NHibernate.Mapping.ByCode; +using NUnit.Framework; +using SharpTestsEx; + +namespace NHibernate.Test.MappingByCode.ConventionModelMapperTests +{ + public class PropertyToFieldAccessorTest + { + private class MyClass + { + public int Id { get; set; } + private string aField; + public int AProp { get; set; } + + private ICollection<int> withDifferentBackField; + public IEnumerable<int> WithDifferentBackField + { + get { return withDifferentBackField; } + set { withDifferentBackField = value as ICollection<int>; } + } + + private string readOnlyWithSameBackField; + public string ReadOnlyWithSameBackField + { + get { return readOnlyWithSameBackField; } + } + + public string PropertyWithoutField + { + get { return ""; } + } + + private string sameTypeOfBackField; + public string SameTypeOfBackField + { + get { return sameTypeOfBackField; } + set { sameTypeOfBackField = value; } + } + + private int setOnlyProperty; + public int SetOnlyProperty + { + set { setOnlyProperty = value; } + } + } + + [Test] + public void WhenFieldAccessToField() + { + var member = typeof(MyClass).GetField("aField",BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly); + var mapper = new ConventionModelMapper(); + mapper.Class<MyClass>(mc => mc.Property(member, x => { })); + var hbmMapping = mapper.CompileMappingFor(new[] { typeof(MyClass) }); + + var hbmClass = hbmMapping.RootClasses[0]; + var hbmProperty = hbmClass.Properties.Single(x => x.Name == "aField"); + hbmProperty.Access.Should().Be("field"); + } + + [Test] + public void WhenAutoPropertyNoAccessor() + { + var mapper = new ConventionModelMapper(); + var hbmMapping = mapper.CompileMappingFor(new[] { typeof(MyClass) }); + + var hbmClass = hbmMapping.RootClasses[0]; + var hbmProperty = hbmClass.Properties.Single(x => x.Name == "AProp"); + hbmProperty.Access.Should().Be.NullOrEmpty(); + } + + [Test] + public void WhenPropertyWithSameBackFieldNoMatch() + { + var mapper = new ConventionModelMapper(); + var hbmMapping = mapper.CompileMappingFor(new[] { typeof(MyClass) }); + + var hbmClass = hbmMapping.RootClasses[0]; + var hbmProperty = hbmClass.Properties.Single(x => x.Name == "SameTypeOfBackField"); + hbmProperty.Access.Should().Be.NullOrEmpty(); + } + + [Test] + public void WhenReadOnlyPropertyWithSameBackFieldNoMatch() + { + var mapper = new ConventionModelMapper(); + var hbmMapping = mapper.CompileMappingFor(new[] { typeof(MyClass) }); + + var hbmClass = hbmMapping.RootClasses[0]; + var hbmProperty = hbmClass.Properties.Single(x => x.Name == "ReadOnlyWithSameBackField"); + hbmProperty.Access.Should().Not.Contain("field"); + } + + [Test] + public void WhenPropertyWithoutFieldNoMatch() + { + var mapper = new ConventionModelMapper(); + mapper.Class<MyClass>(mc => mc.Property(x => x.PropertyWithoutField)); + + var hbmMapping = mapper.CompileMappingFor(new[] {typeof (MyClass)}); + + var hbmClass = hbmMapping.RootClasses[0]; + var hbmProperty = hbmClass.Properties.Single(x => x.Name == "PropertyWithoutField"); + hbmProperty.Access.Should().Not.Contain("field"); + } + + [Test] + public void WhenPropertyWithDifferentBackFieldMatch() + { + var mapper = new ConventionModelMapper(); + var hbmMapping = mapper.CompileMappingFor(new[] { typeof(MyClass) }); + + var hbmClass = hbmMapping.RootClasses[0]; + var hbmProperty = hbmClass.Properties.Single(x => x.Name == "WithDifferentBackField"); + hbmProperty.Access.Should().Contain("field"); + } + + [Test] + public void WhenSetOnlyPropertyNoMatch() + { + var mapper = new ConventionModelMapper(); + var hbmMapping = mapper.CompileMappingFor(new[] { typeof(MyClass) }); + + var hbmClass = hbmMapping.RootClasses[0]; + var hbmProperty = hbmClass.Properties.Single(x => x.Name == "SetOnlyProperty"); + hbmProperty.Access.Should().Not.Contain("field"); + } + } +} \ 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-13 19:03:48 UTC (rev 5692) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-04-13 20:16:57 UTC (rev 5693) @@ -511,6 +511,7 @@ <Compile Include="Linq\ByMethod\SumTests.cs" /> <Compile Include="Logging\Log4NetLoggerTest.cs" /> <Compile Include="Logging\LoggerProviderTest.cs" /> + <Compile Include="MappingByCode\ConventionModelMapperTests\PropertyToFieldAccessorTest.cs" /> <Compile Include="MappingByCode\ConventionModelMapperTests\SafePoidTests.cs" /> <Compile Include="MappingByCode\ExpliticMappingTests\BagOfNestedComponentsWithParentTest.cs" /> <Compile Include="MappingByCode\ExpliticMappingTests\ClassWithComponentsTest.cs" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |