You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ibatis.apache.org by gb...@apache.org on 2006/03/20 21:46:32 UTC

svn commit: r387305 [2/2] - in /ibatis/trunk/cs/mapper: IBatisNet.Common.Test/ IBatisNet.Common.Test/Domain/ IBatisNet.Common.Test/NUnit/CommonTests/Utilities/ IBatisNet.Common/ IBatisNet.Common/Utilities/Objects/Members/ IBatisNet.DataMapper/ IBatisNe...

Modified: ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/EmitFieldAccessor.cs
URL: http://svn.apache.org/viewcvs/ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/EmitFieldAccessor.cs?rev=387305&r1=387304&r2=387305&view=diff
==============================================================================
--- ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/EmitFieldAccessor.cs (original)
+++ ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/EmitFieldAccessor.cs Mon Mar 20 12:46:29 2006
@@ -29,60 +29,28 @@
 using System.Reflection;
 using System.Reflection.Emit;
 
-
 namespace IBatisNet.Common.Utilities.Objects.Members
 {
 	/// <summary>
 	/// The EmitFieldAccessor class provides an IL-based access   
 	/// to a field of a specified target class.
 	/// </summary>
-	/// <remarks>Not Finish. Throw FieldAccessException on SetValue</remarks>
-	public class EmitFieldAccessor : IMemberAccessor
+	/// <remarks>Will Throw FieldAccessException on private field</remarks>
+    public sealed class EmitFieldAccessor : BaseEmitAccessor
 	{
-		private Type _targetType = null;
-		private string _fieldName = string.Empty;
-		private Type _fieldType = null;
-		private IMemberAccessor _emittedFieldAccessor = null;
-		private AssemblyBuilder _assemblyBuilder = null;
-		private ModuleBuilder _moduleBuilder = null;
-		private object _nullInternal = null;
-
-		private static IDictionary _typeToOpcode = new HybridDictionary();
-
-		/// <summary>
-		/// Static constructor
-		/// "Initialize a private hashtable with type-opCode pairs 
-		/// </summary>
-		static EmitFieldAccessor()
-		{
-			_typeToOpcode[typeof(sbyte)] = OpCodes.Ldind_I1;
-			_typeToOpcode[typeof(byte)] = OpCodes.Ldind_U1;
-			_typeToOpcode[typeof(char)] = OpCodes.Ldind_U2;
-			_typeToOpcode[typeof(short)] = OpCodes.Ldind_I2;
-			_typeToOpcode[typeof(ushort)] = OpCodes.Ldind_U2;
-			_typeToOpcode[typeof(int)] = OpCodes.Ldind_I4;
-			_typeToOpcode[typeof(uint)] = OpCodes.Ldind_U4;
-			_typeToOpcode[typeof(long)] = OpCodes.Ldind_I8;
-			_typeToOpcode[typeof(ulong)] = OpCodes.Ldind_I8;
-			_typeToOpcode[typeof(bool)] = OpCodes.Ldind_I1;
-			_typeToOpcode[typeof(double)] = OpCodes.Ldind_R8;
-			_typeToOpcode[typeof(float)] = OpCodes.Ldind_R4;
-		}
-
-
 		/// <summary>
 		/// Creates a new IL field accessor.
 		/// </summary>
-		/// <param name="targetType">Target object type.</param>
+        /// <param name="targetObjectType">Target object type.</param>
 		/// <param name="fieldName">Field name.</param>
-		/// <param name="assemblyBuilder"></param>
-		/// <param name="moduleBuilder"></param>
-		public EmitFieldAccessor(Type targetType, string fieldName, AssemblyBuilder assemblyBuilder, ModuleBuilder moduleBuilder)
-		{
-			_assemblyBuilder = assemblyBuilder;
-			_moduleBuilder = moduleBuilder;
-			_targetType = targetType;
-			_fieldName = fieldName;
+        /// <param name="assemBuilder"></param>
+        /// <param name="modBuilder"></param>
+		public EmitFieldAccessor(Type targetObjectType, string fieldName, AssemblyBuilder assemBuilder, ModuleBuilder modBuilder)
+		{
+            assemblyBuilder = assemBuilder;
+            moduleBuilder = modBuilder;
+            targetType = targetObjectType;
+            memberName = fieldName;
 
 			FieldInfo fieldInfo = targetType.GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);
 
@@ -91,45 +59,23 @@
 			{
 				throw new MissingMethodException(
 					string.Format("Field \"{0}\" does not exist for type "
-					+ "{1}.", fieldName, targetType));
+                    + "{1}.", fieldName, targetObjectType));
 			}
 			else
 			{
-				this._fieldType = fieldInfo.FieldType;
+                memberType = fieldInfo.FieldType;
 				this.EmitIL();
 			}
 		}
 
-		
-		/// <summary>
-		/// This method a new type oject for the the field accessor class 
-		/// that will provide dynamic access.
-		/// </summary>
-		private void EmitIL()
-		{
-			// Create a new type oject for the the field accessor class.
-			EmitType();
-
-			// Create a new instance
-			_emittedFieldAccessor = _assemblyBuilder.CreateInstance("FieldAccessorFor" + _targetType.FullName + _fieldName) as IMemberAccessor;
-            
-			_nullInternal = GetNullInternal(_fieldType);
-
-			if(_emittedFieldAccessor == null)
-			{
-				throw new MethodAccessException(
-					string.Format("Unable to create field accessor for \"{0}\".", _fieldType));
-			}
-		}
-
-		
+				
 		/// <summary>
 		/// Create an type that will provide the get and set methods.
 		/// </summary>
-		private void EmitType()
+        protected override void EmitType()
 		{
 			// Define a public class named "FieldAccessorFor.FullTagetTypeName.FieldName" in the assembly.
-			TypeBuilder typeBuilder = _moduleBuilder.DefineType("FieldAccessorFor" + _targetType.FullName + _fieldName, TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Sealed);
+            TypeBuilder typeBuilder = moduleBuilder.DefineType("MemberAccessorFor" + targetType.FullName + memberName, TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Sealed);
 
 			// Mark the class as implementing IMemberAccessor. 
 			typeBuilder.AddInterfaceImplementation(typeof(IMemberAccessor));
@@ -147,25 +93,21 @@
 			// Get an ILGenerator and used it to emit the IL that we want.
 			ILGenerator getIL = getMethod.GetILGenerator();
 
-			FieldInfo targetField = _targetType.GetField(_fieldName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);
+            FieldInfo targetField = targetType.GetField(memberName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);
 			
 			// Emit the IL for get access. 
 			if(targetField != null)
 			{
+                // We need a reference to the current instance (stored in local argument index 1) 
+                // so Ldfld can load from the correct instance (this one).
 				getIL.Emit(OpCodes.Ldarg_1); 
-				getIL.Emit(OpCodes.Castclass, targetField.DeclaringType); 
-				getIL.Emit(OpCodes.Ldfld, targetField); 
-
-//				getIL.DeclareLocal(typeof(object));
-//				getIL.Emit(OpCodes.Ldarg_0);//Load the first argument,(target object)
-//				getIL.Emit(OpCodes.Castclass, _targetType);	//Cast to the source type
-//				getIL.Emit(OpCodes.Ldfld, targetField);
-//				if(targetField.FieldType.IsValueType)
-//				{
-//					getIL.Emit(OpCodes.Box, targetField.FieldType); //Box if necessary
-//				}
-//				getIL.Emit(OpCodes.Stloc_0);
-//				getIL.Emit(OpCodes.Ldloc_0);
+				getIL.Emit(OpCodes.Ldfld, targetField);
+                if (memberType.IsValueType)
+                {
+                    // Now, we execute the box opcode, which pops the value of field 'x',
+                    // returning a reference to the filed value boxed as an object.
+                    getIL.Emit(OpCodes.Box, targetField.FieldType); 
+                }
 			}
 			else
 			{
@@ -185,8 +127,26 @@
 			// Emit the IL for the set access. 
 			if(targetField != null)
 			{
-				setIL.Emit(OpCodes.Ldarg_0);//Load the first argument (target object)
-				setIL.Emit(OpCodes.Ldarg_1);//Load the second argument (value object)
+				setIL.Emit(OpCodes.Ldarg_1);//Load the first argument (target object)
+                setIL.Emit(OpCodes.Castclass, targetType); //Cast to the source type
+				setIL.Emit(OpCodes.Ldarg_2);//Load the second argument (value object)
+                if (memberType.IsValueType)
+                {
+                    setIL.Emit(OpCodes.Unbox, memberType); //Unbox it 	
+                    if (typeToOpcode[memberType] != null)
+                    {
+                        OpCode load = (OpCode)typeToOpcode[memberType];
+                        setIL.Emit(load); //and load
+                    }
+                    else
+                    {
+                        setIL.Emit(OpCodes.Ldobj, memberType);
+                    }
+                }
+                else
+                {
+                    setIL.Emit(OpCodes.Castclass, memberType); //Cast class
+                }
 				setIL.Emit(OpCodes.Stfld, targetField); //Set the field value
 			}
 			else
@@ -199,48 +159,6 @@
 			typeBuilder.CreateType();
 		}
 
-		/// <summary>
-		/// Get the null value for a given type
-		/// </summary>
-		/// <param name="type"></param>
-		/// <returns></returns>
-		private object GetNullInternal(Type type)
-		{
-			if (type.IsValueType)
-			{
-				if (type.IsEnum) 
-				{ 
-					return GetNullInternal(  Enum.GetUnderlyingType(type) );
-				}
-
-				if (type.IsPrimitive)
-				{
-					if (type == typeof(Int32)) {return 0; }
-					if (type == typeof(Double)) {return (Double)0; }
-					if (type == typeof(Int16)) {return (Int16)0; }
-					if (type == typeof(SByte)) {return (SByte)0; }
-					if (type == typeof(Int64)) {return (Int64)0; }
-					if (type == typeof(Byte)) {return (Byte)0; }
-					if (type == typeof(UInt16)) {return (UInt16)0; }
-					if (type == typeof(UInt32)) {return (UInt32)0; }
-					if (type == typeof(UInt64)) {return (UInt64)0; }
-					if (type == typeof(UInt64)) {return (UInt64)0; }
-					if (type == typeof(Single)) {return (Single)0; }
-					if (type == typeof(Boolean)) {return false; }
-					if (type == typeof(char)) {return '\0'; }
-				}
-				else
-				{
-					if (type == typeof(DateTime)) {return DateTime.MinValue; }
-					if (type == typeof(Decimal)) {return 0m; }
-					if (type == typeof(Guid)) {return Guid.Empty; }
-					if (type == typeof(TimeSpan)) { return TimeSpan.MinValue; }
-				}
-			}
- 
-			return null;
-		}
-
 
 		#region IMemberAccessor Members
 
@@ -249,9 +167,9 @@
 		/// </summary>
 		/// <param name="target">Target object.</param>
 		/// <returns>Property value.</returns>
-		public object Get(object target)
+        public override object Get(object target)
 		{
-			return _emittedFieldAccessor.Get(target);
+            return emittedMemberAccessor.Get(target);
 		}
 
 		/// <summary>
@@ -259,15 +177,15 @@
 		/// </summary>
 		/// <param name="target">Target object.</param>
 		/// <param name="value">Value to set.</param>
-		public void Set(object target, object value)
+        public override void Set(object target, object value)
 		{
 			object newValue = value;
 			if (newValue == null)
 			{
 				// If the value to assign is null, assign null internal value
-				newValue = _nullInternal;
+				newValue = nullInternal;
 			}
-			_emittedFieldAccessor.Set(target, newValue);
+            emittedMemberAccessor.Set(target, newValue);
 		}
 
 		#endregion

Modified: ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/EmitPropertyAccessor.cs
URL: http://svn.apache.org/viewcvs/ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/EmitPropertyAccessor.cs?rev=387305&r1=387304&r2=387305&view=diff
==============================================================================
--- ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/EmitPropertyAccessor.cs (original)
+++ ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/EmitPropertyAccessor.cs Mon Mar 20 12:46:29 2006
@@ -35,20 +35,11 @@
     /// The EmitPropertyAccessor class provides an IL-based access   
     /// to a property of a specified target class.
     /// </summary>
-    public class EmitPropertyAccessor : IMemberAccessor
+    public sealed class EmitPropertyAccessor : BaseEmitAccessor, IPropertyAccessor
 	{
-        private Type _targetType = null;
-        private string _propertyName = string.Empty;
-        private Type _propertyType = null;
-        private IMemberAccessor _emittedPropertyAccessor = null;
-		private AssemblyBuilder _assemblyBuilder = null;
-		private ModuleBuilder _moduleBuilder = null;
-        private object _nullInternal = null;
 		private bool _canRead = false;
 		private bool _canWrite = false;
 
-		private static IDictionary _typeToOpcode = new HybridDictionary();
-
 		/// <summary>
 		/// Gets a value indicating whether the property can be read. 
 		/// </summary>
@@ -64,41 +55,20 @@
 		{
 			get { return _canWrite; }
 		}
-
-        /// <summary>
-        /// Static constructor
-        /// "Initialize a private hashtable with type-opCode pairs 
-        /// </summary>
-        static EmitPropertyAccessor()
-        {
-            _typeToOpcode[typeof(sbyte)] = OpCodes.Ldind_I1;
-            _typeToOpcode[typeof(byte)] = OpCodes.Ldind_U1;
-            _typeToOpcode[typeof(char)] = OpCodes.Ldind_U2;
-            _typeToOpcode[typeof(short)] = OpCodes.Ldind_I2;
-            _typeToOpcode[typeof(ushort)] = OpCodes.Ldind_U2;
-            _typeToOpcode[typeof(int)] = OpCodes.Ldind_I4;
-            _typeToOpcode[typeof(uint)] = OpCodes.Ldind_U4;
-            _typeToOpcode[typeof(long)] = OpCodes.Ldind_I8;
-            _typeToOpcode[typeof(ulong)] = OpCodes.Ldind_I8;
-            _typeToOpcode[typeof(bool)] = OpCodes.Ldind_I1;
-            _typeToOpcode[typeof(double)] = OpCodes.Ldind_R8;
-            _typeToOpcode[typeof(float)] = OpCodes.Ldind_R4;
-        }
-
-        		
+       		
 		/// <summary>
 		/// Creates a new IL property accessor.
 		/// </summary>
-		/// <param name="targetType">Target object type.</param>
+        /// <param name="targetObjectType">Target object type.</param>
         /// <param name="propertyName">Property name.</param>
-        /// <param name="assemblyBuilder"></param>
-        /// <param name="moduleBuilder"></param>
-        public EmitPropertyAccessor(Type targetType, string propertyName, AssemblyBuilder assemblyBuilder, ModuleBuilder moduleBuilder)
-		{
-			_assemblyBuilder = assemblyBuilder;
-			_moduleBuilder = moduleBuilder;
-			_targetType = targetType;
-            _propertyName = propertyName;
+        /// <param name="assBuilder"></param>
+        /// <param name="modBuilder"></param>
+        public EmitPropertyAccessor(Type targetObjectType, string propertyName, AssemblyBuilder assBuilder, ModuleBuilder modBuilder)
+		{
+            assemblyBuilder = assBuilder;
+            moduleBuilder = modBuilder;
+            targetType = targetObjectType;
+            memberName = propertyName;
 
 			PropertyInfo propertyInfo = targetType.GetProperty(propertyName);
 
@@ -111,7 +81,7 @@
 			}
 			else
 			{
-				_propertyType = propertyInfo.PropertyType;
+				memberType = propertyInfo.PropertyType;
 				_canRead = propertyInfo.CanRead;
 				_canWrite = propertyInfo.CanWrite;
                 this.EmitIL();
@@ -124,17 +94,17 @@
 		/// </summary>
 		/// <param name="target">Target object.</param>
 		/// <returns>Property value.</returns>
-		public object Get(object target)
+        public override object Get(object target)
 		{
 			if (_canRead)
 			{
-				return _emittedPropertyAccessor.Get(target);
+				return emittedMemberAccessor.Get(target);
 			}
 			else
 			{
 				throw new MissingMethodException(
 					string.Format("Property \"{0}\" on type "
-					+ "{1} doesn't have a get method.", _propertyName, _targetType));
+					+ "{1} doesn't have a get method.", memberName, targetType));
 			}
 		}
 
@@ -144,7 +114,7 @@
 		/// </summary>
 		/// <param name="target">Target object.</param>
 		/// <param name="value">Value to set.</param>
-		public void Set(object target, object value)
+        public override void Set(object target, object value)
 		{
 			if (_canWrite)
 			{
@@ -152,94 +122,30 @@
 				if (newValue == null)
 				{
 					// If the value to assign is null, assign null internal value
-					newValue = _nullInternal;
+					newValue = nullInternal;
 				}
 
-				_emittedPropertyAccessor.Set(target, newValue);
+				emittedMemberAccessor.Set(target, newValue);
 			}
 			else
 			{
 				throw new MissingMethodException(
 					string.Format("Property \"{0}\" on type "
-					+ "{1} doesn't have a set method.", _propertyName, _targetType));
+					+ "{1} doesn't have a set method.", memberName, targetType));
 			}
 		}
 
 
 		#endregion
 
-		/// <summary>
-		/// Get the null value for a given type
-		/// </summary>
-		/// <param name="type"></param>
-		/// <returns></returns>
-        private object GetNullInternal(Type type)
-        {
-            if (type.IsValueType)
-            {
-                if (type.IsEnum) 
-				{ 
-					return GetNullInternal(  Enum.GetUnderlyingType(type) );
-				}
-
-                if (type.IsPrimitive)
-                {
-                    if (type == typeof(Int32)) {return 0; }
-                    if (type == typeof(Double)) {return (Double)0; }
-                    if (type == typeof(Int16)) {return (Int16)0; }
-                    if (type == typeof(SByte)) {return (SByte)0; }
-                    if (type == typeof(Int64)) {return (Int64)0; }
-                    if (type == typeof(Byte)) {return (Byte)0; }
-                    if (type == typeof(UInt16)) {return (UInt16)0; }
-                    if (type == typeof(UInt32)) {return (UInt32)0; }
-                    if (type == typeof(UInt64)) {return (UInt64)0; }
-                    if (type == typeof(UInt64)) {return (UInt64)0; }
-                    if (type == typeof(Single)) {return (Single)0; }
-                    if (type == typeof(Boolean)) {return false; }
-                    if (type == typeof(char)) {return '\0'; }
-                }
-                else
-                {
-                    if (type == typeof(DateTime)) {return DateTime.MinValue; }
-                    if (type == typeof(Decimal)) {return 0m; }
-                    if (type == typeof(Guid)) {return Guid.Empty; }
-                    if (type == typeof(TimeSpan)) { return TimeSpan.MinValue; }
-                }
-            }
- 
-            return null;
-        }
-
-
-		/// <summary>
-		/// This method a new type oject for the the property accessor class 
-		/// that will provide dynamic access.
-		/// </summary>
-		private void EmitIL()
-		{
-			// Create a new type oject for the the property accessor class.
-            EmitType();
-
-			// Create a new instance
-            _emittedPropertyAccessor = _assemblyBuilder.CreateInstance("PropertyAccessorFor" + _targetType.FullName + _propertyName) as IMemberAccessor;
-            
-            _nullInternal = GetNullInternal(_propertyType);
-
-			if(_emittedPropertyAccessor == null)
-			{
-                throw new MethodAccessException(
-					string.Format("Unable to create property accessor for \"{0}\".", _propertyName));
-			}
-		}
-
 		
 		/// <summary>
 		/// Create an type that will provide the get and set access method.
 		/// </summary>
-		private void EmitType()
+        protected override void EmitType()
 		{
 			// Define a public class named "PropertyAccessorFor.FullTagetTypeName.PropertyName" in the assembly.
-            TypeBuilder typeBuilder = _moduleBuilder.DefineType("PropertyAccessorFor" + _targetType.FullName + _propertyName, TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Sealed);
+            TypeBuilder typeBuilder = moduleBuilder.DefineType("MemberAccessorFor" + targetType.FullName + memberName, TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Sealed);
 
 			// Mark the class as implementing IMemberAccessor. 
 			typeBuilder.AddInterfaceImplementation(typeof(IMemberAccessor));
@@ -259,13 +165,13 @@
 			ILGenerator getIL = getMethod.GetILGenerator();
 
 			// Emit the IL for get access. 
-			MethodInfo targetGetMethod = _targetType.GetMethod("get_" + _propertyName);
+			MethodInfo targetGetMethod = targetType.GetMethod("get_" + memberName);
 
 			if(targetGetMethod != null)
 			{
 				getIL.DeclareLocal(typeof(object));
 				getIL.Emit(OpCodes.Ldarg_1);	//Load the first argument,(target object)
-				getIL.Emit(OpCodes.Castclass, _targetType);	//Cast to the source type
+				getIL.Emit(OpCodes.Castclass, targetType);	//Cast to the source type
 				getIL.EmitCall(OpCodes.Call, targetGetMethod, null); //Get the property value
 				if(targetGetMethod.ReturnType.IsValueType)
 				{
@@ -290,22 +196,23 @@
 				setParamTypes);
 
 			// Get an ILGenerator and  used to emit the IL that we want.
+            // Set(object, value);
 			ILGenerator setIL = setMethod.GetILGenerator();
 			// Emit the IL for the set access. 
-			MethodInfo targetSetMethod = _targetType.GetMethod("set_" + _propertyName);
+			MethodInfo targetSetMethod = targetType.GetMethod("set_" + memberName);
 			if(targetSetMethod != null)
 			{
 				Type paramType = targetSetMethod.GetParameters()[0].ParameterType;
 				setIL.DeclareLocal(paramType);
 				setIL.Emit(OpCodes.Ldarg_1); //Load the first argument (target object)
-				setIL.Emit(OpCodes.Castclass, _targetType); //Cast to the source type
+				setIL.Emit(OpCodes.Castclass, targetType); //Cast to the source type
 				setIL.Emit(OpCodes.Ldarg_2); //Load the second argument (value object)
 				if(paramType.IsValueType)
 				{
 					setIL.Emit(OpCodes.Unbox, paramType); //Unbox it 	
-					if(_typeToOpcode[paramType]!=null)					
+					if(typeToOpcode[paramType]!=null)					
 					{
-						OpCode load = (OpCode)_typeToOpcode[paramType];
+						OpCode load = (OpCode)typeToOpcode[paramType];
 						setIL.Emit(load); //and load
 					}
 					else

Added: ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/IEmitPropertyAccessor.cs
URL: http://svn.apache.org/viewcvs/ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/IEmitPropertyAccessor.cs?rev=387305&view=auto
==============================================================================
--- ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/IEmitPropertyAccessor.cs (added)
+++ ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/IEmitPropertyAccessor.cs Mon Mar 20 12:46:29 2006
@@ -0,0 +1,36 @@
+#region Apache Notice
+/*****************************************************************************
+ * $Revision: 374175 $
+ * $LastChangedDate$
+ * $LastChangedBy$
+ * 
+ * iBATIS.NET Data Mapper
+ * Copyright (C) 2006/2005 - The Apache Software Foundation
+ *  
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ ********************************************************************************/
+#endregion
+
+namespace IBatisNet.Common.Utilities.Objects.Members
+{
+    /// <summary>
+    /// Property accessor property
+    /// </summary>
+    interface IPropertyAccessor
+    {
+        bool CanRead { get; }
+        bool CanWrite { get; }
+    }
+}

Propchange: ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/IEmitPropertyAccessor.cs
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/IEmitPropertyAccessor.cs
------------------------------------------------------------------------------
    svn:keywords = Id LastChangedDate LastChangedBy

Modified: ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/MemberAccessorFactory.cs
URL: http://svn.apache.org/viewcvs/ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/MemberAccessorFactory.cs?rev=387305&r1=387304&r2=387305&view=diff
==============================================================================
--- ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/MemberAccessorFactory.cs (original)
+++ ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/MemberAccessorFactory.cs Mon Mar 20 12:46:29 2006
@@ -66,16 +66,16 @@
 				// Detect runtime environment and create the appropriate factory
 				if (Environment.Version.Major >= 2)
 				{
-					// To Do : a custom factory for .NET V2
+					// To Do : a custom factory for .NET V2 ?
 					// optimize with DynamicMethod or Delegate.CreateDelegate
 					_createPropertyAccessor = new CreateMemberPropertyAccessor(CreateEmitPropertyAccessor);
-					_createFieldAccessor = new CreateMemberFieldAccessor(CreateEmitFieldAccessor);
+                    _createFieldAccessor = new CreateMemberFieldAccessor(CreateFieldAccessor);
 					
 				}
 				else
 				{
 					_createPropertyAccessor = new CreateMemberPropertyAccessor(CreateEmitPropertyAccessor);
-					_createFieldAccessor = new CreateMemberFieldAccessor(CreateReflectionFieldAccessor);//CreateEmitFieldAccessor
+                    _createFieldAccessor = new CreateMemberFieldAccessor(CreateFieldAccessor);
 				}
 			}
 			else
@@ -160,9 +160,18 @@
 		/// <param name="targetType">Target object type.</param>
 		/// <param name="fieldName">Field name.</param>
 		/// <returns>null if the generation fail</returns>
-		private IMemberAccessor CreateEmitFieldAccessor(Type targetType, string fieldName)
+        private IMemberAccessor CreateFieldAccessor(Type targetType, string fieldName)
 		{
-			return new EmitFieldAccessor(targetType, fieldName, _assemblyBuilder, _moduleBuilder);
+            FieldInfo fieldInfo = targetType.GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);
+
+            if (fieldInfo.FieldType.IsPublic)
+            {
+			    return new EmitFieldAccessor(targetType, fieldName, _assemblyBuilder, _moduleBuilder);
+            }
+            else
+            {
+                return new ReflectionFieldAccessor(targetType, fieldName);
+            }
 		}
 
 		/// <summary>

Modified: ibatis/trunk/cs/mapper/IBatisNet.DataMapper/Configuration/DomSqlMapBuilder.cs
URL: http://svn.apache.org/viewcvs/ibatis/trunk/cs/mapper/IBatisNet.DataMapper/Configuration/DomSqlMapBuilder.cs?rev=387305&r1=387304&r2=387305&view=diff
==============================================================================
--- ibatis/trunk/cs/mapper/IBatisNet.DataMapper/Configuration/DomSqlMapBuilder.cs (original)
+++ ibatis/trunk/cs/mapper/IBatisNet.DataMapper/Configuration/DomSqlMapBuilder.cs Mon Mar 20 12:46:29 2006
@@ -40,6 +40,7 @@
 using IBatisNet.Common.Logging;
 using IBatisNet.Common.Utilities;
 using IBatisNet.Common.Utilities.Objects;
+using IBatisNet.Common.Utilities.Objects.Members;
 using IBatisNet.Common.Xml;
 using IBatisNet.DataMapper.Configuration.Alias;
 using IBatisNet.DataMapper.Configuration.Cache;
@@ -651,7 +652,7 @@
 			Reset();
 
             // To do, analyse config file to set allowCodeGeneration on object factory
-			_configScope.SqlMapper = new SqlMapper( new ObjectFactory(true), new TypeHandlerFactory() );
+			_configScope.SqlMapper = new SqlMapper( new ObjectFactory(true), new TypeHandlerFactory() , new MemberAccessorFactory(true) );
 
 
 			#region Cache Alias

Modified: ibatis/trunk/cs/mapper/IBatisNet.DataMapper/Scope/ConfigurationScope.cs
URL: http://svn.apache.org/viewcvs/ibatis/trunk/cs/mapper/IBatisNet.DataMapper/Scope/ConfigurationScope.cs?rev=387305&r1=387304&r2=387305&view=diff
==============================================================================
--- ibatis/trunk/cs/mapper/IBatisNet.DataMapper/Scope/ConfigurationScope.cs (original)
+++ ibatis/trunk/cs/mapper/IBatisNet.DataMapper/Scope/ConfigurationScope.cs Mon Mar 20 12:46:29 2006
@@ -34,6 +34,7 @@
 using IBatisNet.Common;
 using IBatisNet.Common.Utilities;
 using IBatisNet.Common.Utilities.Objects;
+using IBatisNet.Common.Utilities.Objects.Members;
 using IBatisNet.DataMapper.TypeHandlers;
 
 #endregion
@@ -93,6 +94,14 @@
         public IObjectFactory ObjectFactory
         {
             get { return _sqlMapper.ObjectFactory; }
+        }
+
+        /// <summary>
+        /// The factory which build MemberAccessorFactory
+        /// </summary>
+        public MemberAccessorFactory MemberAccessorFactory
+        {
+            get { return _sqlMapper.MemberAccessorFactory; }
         }
 
 		/// <summary>

Modified: ibatis/trunk/cs/mapper/IBatisNet.DataMapper/SqlMapper.cs
URL: http://svn.apache.org/viewcvs/ibatis/trunk/cs/mapper/IBatisNet.DataMapper/SqlMapper.cs?rev=387305&r1=387304&r2=387305&view=diff
==============================================================================
--- ibatis/trunk/cs/mapper/IBatisNet.DataMapper/SqlMapper.cs (original)
+++ ibatis/trunk/cs/mapper/IBatisNet.DataMapper/SqlMapper.cs Mon Mar 20 12:46:29 2006
@@ -38,6 +38,7 @@
 using IBatisNet.Common;
 using IBatisNet.Common.Utilities;
 using IBatisNet.Common.Utilities.Objects;
+using IBatisNet.Common.Utilities.Objects.Members;
 using IBatisNet.DataMapper.Configuration;
 using IBatisNet.DataMapper.Configuration.Cache;
 using IBatisNet.DataMapper.Configuration.ParameterMapping;
@@ -105,7 +106,7 @@
 		/// </summary>
 		private SessionHolder _sessionHolder = null;
         private IObjectFactory _objectFactory = null;
-
+        private MemberAccessorFactory _memberAccessorFactory = null;
 		#endregion
 
 		#region Properties
@@ -162,15 +163,27 @@
         {
             get { return _objectFactory; }
         }
+
+        /// <summary>
+        /// The factory which build MemberAccessorFactory
+        /// </summary>
+        public MemberAccessorFactory MemberAccessorFactory
+        {
+            get { return _memberAccessorFactory; }
+        }
 		#endregion
 
 		#region Constructor (s) / Destructor
 		/// <summary>
 		/// Create a new SqlMap
 		/// </summary>
-		internal SqlMapper(IObjectFactory objectFactory, TypeHandlerFactory typeHandlerFactory) 
+        /// <param name="objectFactory"></param>
+        /// <param name="typeHandlerFactory"></param>
+        /// <param name="memberAccessorFactory"></param>
+        internal SqlMapper(IObjectFactory objectFactory, TypeHandlerFactory typeHandlerFactory, MemberAccessorFactory memberAccessorFactory) 
 		{
             _objectFactory = objectFactory;
+			_memberAccessorFactory = memberAccessorFactory;
 			_typeHandlerFactory = typeHandlerFactory;
 			_id = HashCodeProvider.GetIdentityHashCode(this).ToString();
 			_sessionHolder = new SessionHolder(_id);