|
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.
|