From: <fab...@us...> - 2011-04-13 20:35:44
|
Revision: 5695 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5695&view=rev Author: fabiomaulo Date: 2011-04-13 20:35:38 +0000 (Wed, 13 Apr 2011) Log Message: ----------- ConventionModelMapper safe accessors Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Mapping/ByCode/ConventionModelMapper.cs Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/ConventionModelMapper.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/ConventionModelMapper.cs 2011-04-13 20:19:46 UTC (rev 5694) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/ConventionModelMapper.cs 2011-04-13 20:35:38 UTC (rev 5695) @@ -19,18 +19,81 @@ BeforeMapClass += NoSetterPoidToField; BeforeMapProperty += MemberToFieldAccessor; + BeforeMapProperty += MemberNoSetterToField; + BeforeMapProperty += MemberReadOnlyAccessor; + BeforeMapBag += MemberToFieldAccessor; BeforeMapSet += MemberToFieldAccessor; BeforeMapMap += MemberToFieldAccessor; BeforeMapList += MemberToFieldAccessor; + BeforeMapBag += MemberNoSetterToField; + BeforeMapSet += MemberNoSetterToField; + BeforeMapMap += MemberNoSetterToField; + BeforeMapList += MemberNoSetterToField; + BeforeMapBag += MemberReadOnlyAccessor; + BeforeMapSet += MemberReadOnlyAccessor; + BeforeMapMap += MemberReadOnlyAccessor; + BeforeMapList += MemberReadOnlyAccessor; BeforeMapManyToOne += MemberToFieldAccessor; BeforeMapOneToOne += MemberToFieldAccessor; BeforeMapAny += MemberToFieldAccessor; + BeforeMapManyToOne += MemberNoSetterToField; + BeforeMapOneToOne += MemberNoSetterToField; + BeforeMapAny += MemberNoSetterToField; + BeforeMapManyToOne += MemberReadOnlyAccessor; + BeforeMapOneToOne += MemberReadOnlyAccessor; + BeforeMapAny += MemberReadOnlyAccessor; } - void MemberToFieldAccessor(IModelInspector modelInspector, PropertyPath member, IAccessorPropertyMapper propertyCustomizer) + protected virtual void MemberReadOnlyAccessor(IModelInspector modelInspector, PropertyPath member, IAccessorPropertyMapper propertyCustomizer) { + if (MatchReadOnlyProperty(member.LocalMember)) + { + propertyCustomizer.Access(Accessor.ReadOnly); + } + } + + protected bool MatchReadOnlyProperty(MemberInfo subject) + { + var property = subject as PropertyInfo; + if (property == null) + { + return false; + } + if (CanReadCantWriteInsideType(property) || CanReadCantWriteInBaseType(property)) + { + return PropertyToField.GetBackFieldInfo(property) == null; + } + return false; + } + + private bool CanReadCantWriteInsideType(PropertyInfo property) + { + return !property.CanWrite && property.CanRead && property.DeclaringType == property.ReflectedType; + } + + private 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 virtual void MemberNoSetterToField(IModelInspector modelInspector, PropertyPath member, IAccessorPropertyMapper propertyCustomizer) + { + if (MatchNoSetterProperty(member.LocalMember)) + { + propertyCustomizer.Access(Accessor.NoSetter); + } + } + + protected virtual void MemberToFieldAccessor(IModelInspector modelInspector, PropertyPath member, IAccessorPropertyMapper propertyCustomizer) + { if (MatchPropertyToField(member.LocalMember)) { propertyCustomizer.Access(Accessor.Field); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |