|
From: <fab...@us...> - 2011-04-10 19:27:43
|
Revision: 5654
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5654&view=rev
Author: fabiomaulo
Date: 2011-04-10 19:27:37 +0000 (Sun, 10 Apr 2011)
Log Message:
-----------
SimpleModelInspector with default pattern to discover Persistent properties
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/AccessorPropertyMapper.cs
trunk/nhibernate/src/NHibernate/Mapping/ByCode/SimpleModelInspector.cs
trunk/nhibernate/src/NHibernate/NHibernate.csproj
trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj
Added Paths:
-----------
trunk/nhibernate/src/NHibernate/Mapping/ByCode/PropertyToField.cs
trunk/nhibernate/src/NHibernate.Test/MappingByCode/MixAutomapping/PropertiesExclusionTests.cs
Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/AccessorPropertyMapper.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/AccessorPropertyMapper.cs 2011-04-10 18:32:35 UTC (rev 5653)
+++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/AccessorPropertyMapper.cs 2011-04-10 19:27:37 UTC (rev 5654)
@@ -15,16 +15,7 @@
private readonly System.Type declaringType;
- private readonly Dictionary<string, IFieldNamingStrategy> fieldNamningStrategies =
- new Dictionary<string, IFieldNamingStrategy>
- {
- {"camelcase", new CamelCaseStrategy()},
- {"camelcase-underscore", new CamelCaseUnderscoreStrategy()},
- {"lowercase", new LowerCaseStrategy()},
- {"lowercase-underscore", new LowerCaseUnderscoreStrategy()},
- {"pascalcase-underscore", new PascalCaseUnderscoreStrategy()},
- {"pascalcase-m-underscore", new PascalCaseMUnderscoreStrategy()},
- };
+ private readonly IDictionary<string, IFieldNamingStrategy> fieldNamningStrategies = PropertyToField.DefaultStrategies;
private readonly string propertyName;
private readonly Action<string> setAccessor;
Added: trunk/nhibernate/src/NHibernate/Mapping/ByCode/PropertyToField.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Mapping/ByCode/PropertyToField.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/PropertyToField.cs 2011-04-10 19:27:37 UTC (rev 5654)
@@ -0,0 +1,32 @@
+using System.Collections.Generic;
+using NHibernate.Properties;
+
+namespace NHibernate.Mapping.ByCode
+{
+ public class PropertyToField
+ {
+ private static readonly Dictionary<string, IFieldNamingStrategy> FieldNamningStrategies = new Dictionary<string, IFieldNamingStrategy>
+ {
+ {"camelcase", new CamelCaseStrategy()},
+ {"camelcase-underscore", new CamelCaseUnderscoreStrategy()},
+ {"lowercase", new LowerCaseStrategy()},
+ {"lowercase-underscore", new LowerCaseUnderscoreStrategy()},
+ {"pascalcase-underscore", new PascalCaseUnderscoreStrategy()},
+ {"pascalcase-m-underscore", new PascalCaseMUnderscoreStrategy()},
+ };
+
+ /// <summary>
+ /// Dictionary containing the embedded strategies to find a field giving a property name.
+ /// The key is the "partial-name" of the strategy used in XML mapping.
+ /// The value is an instance of the strategy.
+ /// </summary>
+ public static IDictionary<string, IFieldNamingStrategy> DefaultStrategies
+ {
+ get
+ {
+ // please leave it as no read-only; the user may need to add his strategies or remove existing if he no want his people use it.
+ return FieldNamningStrategies;
+ }
+ }
+ }
+}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/SimpleModelInspector.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Mapping/ByCode/SimpleModelInspector.cs 2011-04-10 18:32:35 UTC (rev 5653)
+++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/SimpleModelInspector.cs 2011-04-10 19:27:37 UTC (rev 5654)
@@ -22,7 +22,7 @@
private Func<System.Type, bool, bool> isComponent;
private Func<MemberInfo, bool, bool> isPersistentId;
- private Func<MemberInfo, bool, bool> isPersistentProperty = (m, declared) => declared;
+ private Func<MemberInfo, bool, bool> isPersistentProperty;
private Func<MemberInfo, bool, bool> isVersion = (m, declared) => declared;
private Func<MemberInfo, bool, bool> isProperty = (m, declared) => declared;
@@ -44,8 +44,53 @@
{
isPersistentId = (m, declared) => declared || MatchPoIdPattern(m);
isComponent = (t, declared) => declared || MatchComponentPattern(t);
+ isPersistentProperty = (m, declared) => declared || MatchNoReadOnlyPropertyPattern(m);
}
+ protected bool MatchNoReadOnlyPropertyPattern(MemberInfo subject)
+ {
+ var isReadOnlyProperty = IsReadOnlyProperty(subject);
+ return !isReadOnlyProperty;
+ }
+
+ protected bool IsReadOnlyProperty(MemberInfo subject)
+ {
+ const BindingFlags defaultBinding = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly;
+
+ var property = subject as PropertyInfo;
+ if (property == null)
+ {
+ return false;
+ }
+ if (CanReadCantWriteInsideType(property) || CanReadCantWriteInBaseType(property))
+ {
+ return !PropertyToField.DefaultStrategies.Values.Any(s => subject.DeclaringType.GetField(s.GetFieldName(property.Name), defaultBinding) != null) || IsAutoproperty(property);
+ }
+ return false;
+ }
+
+ protected bool IsAutoproperty(PropertyInfo property)
+ {
+ return property.ReflectedType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance
+ | BindingFlags.DeclaredOnly).Any(pi => pi.Name == string.Concat("<", property.Name, ">k__BackingField"));
+ }
+
+ protected bool CanReadCantWriteInsideType(PropertyInfo property)
+ {
+ return !property.CanWrite && property.CanRead && property.DeclaringType == property.ReflectedType;
+ }
+
+ protected bool CanReadCantWriteInBaseType(PropertyInfo property)
+ {
+ if (property.DeclaringType == property.ReflectedType)
+ {
+ return false;
+ }
+ var rfprop = property.DeclaringType.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance
+ | BindingFlags.DeclaredOnly).SingleOrDefault(pi => pi.Name == property.Name);
+ return rfprop != null && !rfprop.CanWrite && rfprop.CanRead;
+ }
+
protected bool MatchPoIdPattern(MemberInfo subject)
{
var name = subject.Name;
Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2011-04-10 18:32:35 UTC (rev 5653)
+++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2011-04-10 19:27:37 UTC (rev 5654)
@@ -290,6 +290,7 @@
<Compile Include="Mapping\ByCode\Conformist\JoinedSubclassMapping.cs" />
<Compile Include="Mapping\ByCode\Conformist\SubclassMapping.cs" />
<Compile Include="Mapping\ByCode\Conformist\UnionSubclassMapping.cs" />
+ <Compile Include="Mapping\ByCode\PropertyToField.cs" />
<Compile Include="Mapping\ByCode\SimpleModelInspector.cs" />
<Compile Include="Mapping\ByCode\ExplicitlyDeclaredModel.cs" />
<Compile Include="Mapping\ByCode\FakeModelExplicitDeclarationsHolder.cs" />
Added: trunk/nhibernate/src/NHibernate.Test/MappingByCode/MixAutomapping/PropertiesExclusionTests.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/MappingByCode/MixAutomapping/PropertiesExclusionTests.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/MappingByCode/MixAutomapping/PropertiesExclusionTests.cs 2011-04-10 19:27:37 UTC (rev 5654)
@@ -0,0 +1,103 @@
+using System.Reflection;
+using NHibernate.Mapping.ByCode;
+using NUnit.Framework;
+using SharpTestsEx;
+
+namespace NHibernate.Test.MappingByCode.MixAutomapping
+{
+ public class PropertiesExclusionTests
+ {
+ public class MyEntity
+ {
+ private string noReadOnlyWithField;
+ private string pizza;
+
+ public string ReadOnly
+ {
+ get { return ""; }
+ }
+
+ public string NoReadOnlyWithField
+ {
+ get { return noReadOnlyWithField; }
+ }
+
+ public string NoReadOnly
+ {
+ get { return ""; }
+ set { }
+ }
+
+ public string WriteOnly
+ {
+ set { }
+ }
+
+ public string AutoPropWithPrivateSet { get; private set; }
+ }
+
+ [Test]
+ public void WhenReadonlyDeclaredThenIsPersistentProperty()
+ {
+ var autoinspector = new SimpleModelInspector();
+ var mapper = new ModelMapper(autoinspector);
+ mapper.Class<MyEntity>(map => map.Property(x => x.ReadOnly));
+
+ var inspector = (IModelInspector)autoinspector;
+ inspector.IsPersistentProperty(typeof(MyEntity).GetProperty("ReadOnly")).Should().Be.True();
+ }
+
+ [Test]
+ public void WhenReadonlyNotDeclaredThenIsNotPersistentProperty()
+ {
+ var autoinspector = new SimpleModelInspector();
+ var inspector = (IModelInspector)autoinspector;
+
+ inspector.IsPersistentProperty(typeof(MyEntity).GetProperty("ReadOnly")).Should().Be.False();
+ }
+
+ [Test]
+ public void IncludesReadOnlyWithField()
+ {
+ var autoinspector = new SimpleModelInspector();
+ var inspector = (IModelInspector)autoinspector;
+
+ PropertyInfo pi = typeof(MyEntity).GetProperty("NoReadOnlyWithField");
+ inspector.IsPersistentProperty(pi).Should().Be.True();
+ }
+
+ [Test]
+ public void IncludesNoReadOnly()
+ {
+ var autoinspector = new SimpleModelInspector();
+ var inspector = (IModelInspector)autoinspector;
+
+ PropertyInfo pi = typeof(MyEntity).GetProperty("NoReadOnly");
+ inspector.IsPersistentProperty(pi).Should().Be.True();
+
+ pi = typeof(MyEntity).GetProperty("WriteOnly");
+ inspector.IsPersistentProperty(pi).Should().Be.True();
+ }
+
+ [Test]
+ public void IncludesFields()
+ {
+ var autoinspector = new SimpleModelInspector();
+ var inspector = (IModelInspector)autoinspector;
+
+ var pi = typeof(MyEntity).GetField("pizza", BindingFlags.Instance | BindingFlags.NonPublic);
+ inspector.IsPersistentProperty(pi).Should().Be.True();
+ }
+
+ [Test]
+ public void IncludesAutoprop()
+ {
+ var autoinspector = new SimpleModelInspector();
+ var inspector = (IModelInspector)autoinspector;
+
+ var pi = typeof(MyEntity).GetProperty("AutoPropWithPrivateSet");
+ inspector.IsPersistentProperty(pi).Should().Be.True();
+ }
+
+ }
+}
\ 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-10 18:32:35 UTC (rev 5653)
+++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-04-10 19:27:37 UTC (rev 5654)
@@ -543,6 +543,7 @@
<Compile Include="MappingByCode\MappersTests\SubclassMapperWithJoinPropertiesTest.cs" />
<Compile Include="MappingByCode\MixAutomapping\ComponentsTests.cs" />
<Compile Include="MappingByCode\MixAutomapping\PoidTests.cs" />
+ <Compile Include="MappingByCode\MixAutomapping\PropertiesExclusionTests.cs" />
<Compile Include="MappingByCode\ModelExplicitDeclarationsHolderMergeTest.cs" />
<Compile Include="MappingByCode\NatureDemo\Naturalness\Address.cs" />
<Compile Include="MappingByCode\NatureDemo\Naturalness\Animal.cs" />
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|