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/19 23:02:02 UTC
svn commit: r387044 - in /ibatis/trunk/cs/mapper:
IBatisNet.Common.Test/Domain/
IBatisNet.Common.Test/NUnit/CommonTests/Utilities/ IBatisNet.Common/
IBatisNet.Common/Utilities/Objects/Members/
Author: gbayon
Date: Sun Mar 19 14:02:00 2006
New Revision: 387044
URL: http://svn.apache.org/viewcvs?rev=387044&view=rev
Log:
- Updated member accessor
Added:
ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/EmitPropertyAccessor.cs
- copied, changed from r386699, ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/ILPropertyAccessor.cs
Removed:
ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/ILPropertyAccessor.cs
Modified:
ibatis/trunk/cs/mapper/IBatisNet.Common.Test/Domain/Property.cs
ibatis/trunk/cs/mapper/IBatisNet.Common.Test/NUnit/CommonTests/Utilities/FieldAccessorTest.cs
ibatis/trunk/cs/mapper/IBatisNet.Common/DataSource.cs
ibatis/trunk/cs/mapper/IBatisNet.Common/DbProvider.cs
ibatis/trunk/cs/mapper/IBatisNet.Common/IBatisNet.Common.csproj
ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/EmitFieldAccessor.cs
ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/MemberAccessorFactory.cs
ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/ReflectionFieldAccessor.cs
ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/ReflectionPropertyAccessor.cs
Modified: ibatis/trunk/cs/mapper/IBatisNet.Common.Test/Domain/Property.cs
URL: http://svn.apache.org/viewcvs/ibatis/trunk/cs/mapper/IBatisNet.Common.Test/Domain/Property.cs?rev=387044&r1=387043&r2=387044&view=diff
==============================================================================
--- ibatis/trunk/cs/mapper/IBatisNet.Common.Test/Domain/Property.cs (original)
+++ ibatis/trunk/cs/mapper/IBatisNet.Common.Test/Domain/Property.cs Sun Mar 19 14:02:00 2006
@@ -19,7 +19,7 @@
public class Property
{
private string _string = string.Empty;
- private int _int = int.MinValue;
+ public int _int = int.MinValue;
private DateTime _dateTime = DateTime.MinValue;
private decimal _decimal = decimal.MinValue;
private sbyte _sbyte = sbyte.MinValue;
Modified: ibatis/trunk/cs/mapper/IBatisNet.Common.Test/NUnit/CommonTests/Utilities/FieldAccessorTest.cs
URL: http://svn.apache.org/viewcvs/ibatis/trunk/cs/mapper/IBatisNet.Common.Test/NUnit/CommonTests/Utilities/FieldAccessorTest.cs?rev=387044&r1=387043&r2=387044&view=diff
==============================================================================
--- ibatis/trunk/cs/mapper/IBatisNet.Common.Test/NUnit/CommonTests/Utilities/FieldAccessorTest.cs (original)
+++ ibatis/trunk/cs/mapper/IBatisNet.Common.Test/NUnit/CommonTests/Utilities/FieldAccessorTest.cs Sun Mar 19 14:02:00 2006
@@ -1,17 +1,49 @@
using System;
+using System.Reflection;
+using IBatisNet.Common.Test.Domain;
+using IBatisNet.Common.Utilities;
+using IBatisNet.Common.Utilities.Objects.Members;
+using NUnit.Framework;
namespace IBatisNet.Common.Test.NUnit.CommonTests.Utilities
{
/// <summary>
/// Summary description for FieldAccessorTest.
/// </summary>
+ [TestFixture]
public class FieldAccessorTest
{
- public FieldAccessorTest()
+ /// <summary>
+ /// Test setting an integer property.
+ /// </summary>
+ [Test]
+ public void TestSetInteger()
{
- //
- // TODO: Add constructor logic here
- //
+ Property prop = new Property();
+ prop.Int = -99;
+
+ // Property accessor
+ MemberAccessorFactory factory = new MemberAccessorFactory(true);
+ IMemberAccessor propertyAccessor = factory.CreateMemberAccessor(typeof(Property), "_int");
+ int test = 57;
+ propertyAccessor.Set(prop, test);
+ Assert.AreEqual(test, prop.Int);
+ }
+
+ /// <summary>
+ /// Test getting an integer property.
+ /// </summary>
+ [Test]
+ public void TestGetInteger()
+ {
+ int test = -99;
+ Property prop = new Property();
+ prop.Int = test;
+
+ // Property accessor
+ MemberAccessorFactory factory = new MemberAccessorFactory(true);
+ IMemberAccessor propertyAccessor = factory.CreateMemberAccessor(typeof(Property), "_int");
+ Assert.AreEqual(test, propertyAccessor.Get(prop));
}
}
}
Modified: ibatis/trunk/cs/mapper/IBatisNet.Common/DataSource.cs
URL: http://svn.apache.org/viewcvs/ibatis/trunk/cs/mapper/IBatisNet.Common/DataSource.cs?rev=387044&r1=387043&r2=387044&view=diff
==============================================================================
--- ibatis/trunk/cs/mapper/IBatisNet.Common/DataSource.cs (original)
+++ ibatis/trunk/cs/mapper/IBatisNet.Common/DataSource.cs Sun Mar 19 14:02:00 2006
@@ -1,12 +1,12 @@
#region Apache Notice
/*****************************************************************************
- * $Header: $
- * $Revision: $
- * $Date$
+ * $Revision: 374175 $
+ * $LastChangedDate$
+ * $LastChangedBy$
*
* iBATIS.NET Data Mapper
- * Copyright (C) 2004 - Gilles Bayon
+ * Copyright (C) 2006/2005 - The Apache Software Foundation
*
*
* Licensed under the Apache License, Version 2.0 (the "License");
Modified: ibatis/trunk/cs/mapper/IBatisNet.Common/DbProvider.cs
URL: http://svn.apache.org/viewcvs/ibatis/trunk/cs/mapper/IBatisNet.Common/DbProvider.cs?rev=387044&r1=387043&r2=387044&view=diff
==============================================================================
--- ibatis/trunk/cs/mapper/IBatisNet.Common/DbProvider.cs (original)
+++ ibatis/trunk/cs/mapper/IBatisNet.Common/DbProvider.cs Sun Mar 19 14:02:00 2006
@@ -1,12 +1,12 @@
#region Apache Notice
/*****************************************************************************
- * $Header: $
- * $Revision$
- * $Date$
+ * $Revision: 374175 $
+ * $LastChangedDate$
+ * $LastChangedBy$
*
* iBATIS.NET Data Mapper
- * Copyright (C) 2004 - Gilles Bayon
+ * Copyright (C) 2006/2005 - The Apache Software Foundation
*
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -489,11 +489,12 @@
}
}
+
/// <summary>
/// Create a connection object for this provider.
/// </summary>
/// <returns>An 'IDbConnection' object.</returns>
- public IDbConnection CreateConnection()
+ public virtual IDbConnection CreateConnection()
{
// Cannot do that because on
// IDbCommand.Connection = cmdConnection
@@ -513,11 +514,12 @@
}
}
+
/// <summary>
/// Create a command object for this provider.
/// </summary>
/// <returns>An 'IDbCommand' object.</returns>
- public IDbCommand CreateCommand()
+ public virtual IDbCommand CreateCommand()
{
return _templateConnection.CreateCommand();
}
@@ -526,7 +528,7 @@
/// Create a dataAdapter object for this provider.
/// </summary>
/// <returns>An 'IDbDataAdapter' object.</returns>
- public IDbDataAdapter CreateDataAdapter()
+ public virtual IDbDataAdapter CreateDataAdapter()
{
if (_templateDataAdapterIsICloneable)
{
@@ -539,12 +541,11 @@
}
-
/// <summary>
/// Create a IDbDataParameter object for this provider.
/// </summary>
/// <returns>An 'IDbDataParameter' object.</returns>
- public IDbDataParameter CreateDataParameter()
+ public virtual IDbDataParameter CreateDataParameter()
{
return _templateConnection.CreateCommand().CreateParameter();
}
@@ -555,7 +556,7 @@
/// </summary>
/// <param name="parameterName">The unformatted name of the parameter</param>
/// <returns>A parameter formatted for an IDbCommand.CommandText</returns>
- public string FormatNameForSql(string parameterName)
+ public virtual string FormatNameForSql(string parameterName)
{
return _useParameterPrefixInSql ? (_parameterPrefix + parameterName) : SQLPARAMETER;
}
@@ -569,7 +570,7 @@
/// </remarks>
/// <param name="parameterName">The unformatted name of the parameter</param>
/// <returns>A parameter formatted for an IDbParameter.</returns>
- public string FormatNameForParameter(string parameterName)
+ public virtual string FormatNameForParameter(string parameterName)
{
return _useParameterPrefixInParameter ? (_parameterPrefix + parameterName) : parameterName;
}
Modified: ibatis/trunk/cs/mapper/IBatisNet.Common/IBatisNet.Common.csproj
URL: http://svn.apache.org/viewcvs/ibatis/trunk/cs/mapper/IBatisNet.Common/IBatisNet.Common.csproj?rev=387044&r1=387043&r2=387044&view=diff
==============================================================================
--- ibatis/trunk/cs/mapper/IBatisNet.Common/IBatisNet.Common.csproj (original)
+++ ibatis/trunk/cs/mapper/IBatisNet.Common/IBatisNet.Common.csproj Sun Mar 19 14:02:00 2006
@@ -350,7 +350,7 @@
BuildAction = "Compile"
/>
<File
- RelPath = "Utilities\Objects\Members\ILPropertyAccessor.cs"
+ RelPath = "Utilities\Objects\Members\EmitPropertyAccessor.cs"
SubType = "Code"
BuildAction = "Compile"
/>
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=387044&r1=387043&r2=387044&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 Sun Mar 19 14:02:00 2006
@@ -1,9 +1,34 @@
+#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
+
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Reflection;
using System.Reflection.Emit;
-using IBatisNet.Common.Exceptions;
+
namespace IBatisNet.Common.Utilities.Objects.Members
{
@@ -11,6 +36,7 @@
/// 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
{
private Type _targetType = null;
@@ -53,27 +79,169 @@
/// <param name="moduleBuilder"></param>
public EmitFieldAccessor(Type targetType, string fieldName, AssemblyBuilder assemblyBuilder, ModuleBuilder moduleBuilder)
{
- this._assemblyBuilder = assemblyBuilder;
- this._moduleBuilder = moduleBuilder;
- this._targetType = targetType;
- this._fieldName = fieldName;
+ _assemblyBuilder = assemblyBuilder;
+ _moduleBuilder = moduleBuilder;
+ _targetType = targetType;
+ _fieldName = fieldName;
- FieldInfo fieldInfo = targetType.GetField(fieldName);
+ FieldInfo fieldInfo = targetType.GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);
- // Make sure the property exists
+ // Make sure the field exists
if(fieldInfo == null)
{
- throw new ProbeException(
+ throw new MissingMethodException(
string.Format("Field \"{0}\" does not exist for type "
+ "{1}.", fieldName, targetType));
}
else
{
this._fieldType = fieldInfo.FieldType;
-// this.Emit();
+ 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()
+ {
+ // 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);
+
+ // Mark the class as implementing IMemberAccessor.
+ typeBuilder.AddInterfaceImplementation(typeof(IMemberAccessor));
+
+ // Add a constructor
+ typeBuilder.DefineDefaultConstructor(MethodAttributes.Public);
+
+ // Define a method named "Get" for the get operation (IMemberAccessor).
+ Type[] getParamTypes = new Type[] {typeof(object)};
+ MethodBuilder getMethod = typeBuilder.DefineMethod("Get",
+ MethodAttributes.Public | MethodAttributes.Virtual,
+ typeof(object),
+ getParamTypes);
+
+ // 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);
+
+ // Emit the IL for get access.
+ if(targetField != null)
+ {
+ 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);
+ }
+ else
+ {
+ getIL.ThrowException(typeof(MissingMethodException));
+ }
+ getIL.Emit(OpCodes.Ret);
+
+ // Define a method named "Set" for the set operation (IMemberAccessor).
+ Type[] setParamTypes = new Type[] {typeof(object), typeof(object)};
+ MethodBuilder setMethod = typeBuilder.DefineMethod("Set",
+ MethodAttributes.Public | MethodAttributes.Virtual,
+ null,
+ setParamTypes);
+
+ // Get an ILGenerator and used to emit the IL that we want.
+ ILGenerator setIL = setMethod.GetILGenerator();
+ // 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.Stfld, targetField); //Set the field value
+ }
+ else
+ {
+ setIL.ThrowException(typeof(MissingMethodException));
+ }
+ setIL.Emit(OpCodes.Ret);
+
+ // Load the type
+ 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
/// <summary>
@@ -83,8 +251,7 @@
/// <returns>Property value.</returns>
public object Get(object target)
{
- // TODO: Add EmitFieldAccessor.Get implementation
- return null;
+ return _emittedFieldAccessor.Get(target);
}
/// <summary>
@@ -94,9 +261,17 @@
/// <param name="value">Value to set.</param>
public void Set(object target, object value)
{
- // TODO: Add EmitFieldAccessor.Set implementation
+ object newValue = value;
+ if (newValue == null)
+ {
+ // If the value to assign is null, assign null internal value
+ newValue = _nullInternal;
+ }
+ _emittedFieldAccessor.Set(target, newValue);
}
#endregion
}
}
+
+
Copied: ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/EmitPropertyAccessor.cs (from r386699, ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/ILPropertyAccessor.cs)
URL: http://svn.apache.org/viewcvs/ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/EmitPropertyAccessor.cs?p2=ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/EmitPropertyAccessor.cs&p1=ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/ILPropertyAccessor.cs&r1=386699&r2=387044&rev=387044&view=diff
==============================================================================
--- ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/ILPropertyAccessor.cs (original)
+++ ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/EmitPropertyAccessor.cs Sun Mar 19 14:02:00 2006
@@ -28,7 +28,6 @@
using System.Collections.Specialized;
using System.Reflection;
using System.Reflection.Emit;
-using IBatisNet.Common.Exceptions;
namespace IBatisNet.Common.Utilities.Objects.Members
{
@@ -45,9 +44,27 @@
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>
+ public bool CanRead
+ {
+ get { return _canRead; }
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether the property can be written to.
+ /// </summary>
+ public bool CanWrite
+ {
+ get { return _canWrite; }
+ }
+
/// <summary>
/// Static constructor
/// "Initialize a private hashtable with type-opCode pairs
@@ -78,28 +95,30 @@
/// <param name="moduleBuilder"></param>
public EmitPropertyAccessor(Type targetType, string propertyName, AssemblyBuilder assemblyBuilder, ModuleBuilder moduleBuilder)
{
- this._assemblyBuilder = assemblyBuilder;
- this._moduleBuilder = moduleBuilder;
- this._targetType = targetType;
- this._propertyName = propertyName;
+ _assemblyBuilder = assemblyBuilder;
+ _moduleBuilder = moduleBuilder;
+ _targetType = targetType;
+ _propertyName = propertyName;
- PropertyInfo propertyInfo = targetType.GetProperty(propertyName);
+ PropertyInfo propertyInfo = targetType.GetProperty(propertyName);
// Make sure the property exists
if(propertyInfo == null)
{
- throw new ProbeException(
+ throw new MissingMethodException(
string.Format("Property \"{0}\" does not exist for type "
+ "{1}.", propertyName, targetType));
}
else
{
- this._propertyType = propertyInfo.PropertyType;
- this.Init();
+ _propertyType = propertyInfo.PropertyType;
+ _canRead = propertyInfo.CanRead;
+ _canWrite = propertyInfo.CanWrite;
+ this.EmitIL();
}
}
-
+ #region IMemberAccessor Members
/// <summary>
/// Gets the property value from the specified target.
/// </summary>
@@ -107,9 +126,19 @@
/// <returns>Property value.</returns>
public object Get(object target)
{
- return this._emittedPropertyAccessor.Get(target);
+ if (_canRead)
+ {
+ return _emittedPropertyAccessor.Get(target);
+ }
+ else
+ {
+ throw new MissingMethodException(
+ string.Format("Property \"{0}\" on type "
+ + "{1} doesn't have a get method.", _propertyName, _targetType));
+ }
}
+
/// <summary>
/// Sets the property for the specified target.
/// </summary>
@@ -117,16 +146,33 @@
/// <param name="value">Value to set.</param>
public void Set(object target, object value)
{
- // If the value to assign is null and assign null internal value
- object newValue = value;
- if (newValue == null)
- {
- newValue = _nullInternal;
- }
+ if (_canWrite)
+ {
+ object newValue = value;
+ if (newValue == null)
+ {
+ // If the value to assign is null, assign null internal value
+ newValue = _nullInternal;
+ }
- this._emittedPropertyAccessor.Set(target, newValue);
+ _emittedPropertyAccessor.Set(target, newValue);
+ }
+ else
+ {
+ throw new MissingMethodException(
+ string.Format("Property \"{0}\" on type "
+ + "{1} doesn't have a set method.", _propertyName, _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)
@@ -164,40 +210,44 @@
return null;
}
+
/// <summary>
- /// This method generates creates a new assembly containing
- /// the Type that will provide dynamic access.
+ /// This method a new type oject for the the property accessor class
+ /// that will provide dynamic access.
/// </summary>
- private void Init()
+ private void EmitIL()
{
- // Create the assembly and an instance of the property accessor class.
+ // 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 ProbeException(string.Format("Unable to create property accessor for \"{0}\".", _propertyName));
+ throw new MethodAccessException(
+ string.Format("Unable to create property accessor for \"{0}\".", _propertyName));
}
}
+
/// <summary>
- /// Create an assembly that will provide the get and set methods.
+ /// Create an type that will provide the get and set access method.
/// </summary>
private void EmitType()
{
- // Define a public class named "Property..." in the assembly.
- TypeBuilder typeBuilder = _moduleBuilder.DefineType("PropertyAccessorFor" + _targetType.FullName + _propertyName, TypeAttributes.Public);
+ // 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);
- // Mark the class as implementing IPropertyAccessor.
+ // Mark the class as implementing IMemberAccessor.
typeBuilder.AddInterfaceImplementation(typeof(IMemberAccessor));
// Add a constructor
typeBuilder.DefineDefaultConstructor(MethodAttributes.Public);
- // Define a method for the get operation.
+ // Define a method named "Get" for the get operation (IMemberAccessor).
Type[] getParamTypes = new Type[] {typeof(object)};
MethodBuilder getMethod =
typeBuilder.DefineMethod("Get",
@@ -205,37 +255,33 @@
typeof(object),
getParamTypes);
- // From the method, get an ILGenerator. This is used to
- // emit the IL that we want.
+ // Get an ILGenerator and used it to emit the IL that we want.
ILGenerator getIL = getMethod.GetILGenerator();
- // Emit the IL.
- MethodInfo targetGetMethod = this._targetType.GetMethod("get_" + this._propertyName);
+ // Emit the IL for get access.
+ MethodInfo targetGetMethod = _targetType.GetMethod("get_" + _propertyName);
if(targetGetMethod != null)
{
getIL.DeclareLocal(typeof(object));
getIL.Emit(OpCodes.Ldarg_1); //Load the first argument,(target object)
- getIL.Emit(OpCodes.Castclass, this._targetType); //Cast to the source type
- getIL.EmitCall(OpCodes.Call, targetGetMethod, null); //Get the property value
-
+ getIL.Emit(OpCodes.Castclass, _targetType); //Cast to the source type
+ getIL.EmitCall(OpCodes.Call, targetGetMethod, null); //Get the property value
if(targetGetMethod.ReturnType.IsValueType)
{
- getIL.Emit(OpCodes.Box, targetGetMethod.ReturnType); //Box if necessary
+ getIL.Emit(OpCodes.Box, targetGetMethod.ReturnType); //Box if necessary
}
- getIL.Emit(OpCodes.Stloc_0); //Store it
-
+ getIL.Emit(OpCodes.Stloc_0); //Store it
getIL.Emit(OpCodes.Ldloc_0);
}
else
{
getIL.ThrowException(typeof(MissingMethodException));
}
-
getIL.Emit(OpCodes.Ret);
- // Define a method for the set operation.
+ // Define a method named "Set" for the set operation (IMemberAccessor).
Type[] setParamTypes = new Type[] {typeof(object), typeof(object)};
MethodBuilder setMethod =
typeBuilder.DefineMethod("Set",
@@ -243,29 +289,24 @@
null,
setParamTypes);
- // From the method, get an ILGenerator. This is used to
- // emit the IL that we want.
+ // Get an ILGenerator and used to emit the IL that we want.
ILGenerator setIL = setMethod.GetILGenerator();
- // Emit the IL.
- MethodInfo targetSetMethod = this._targetType.GetMethod("set_" + this._propertyName);
+ // Emit the IL for the set access.
+ MethodInfo targetSetMethod = _targetType.GetMethod("set_" + _propertyName);
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, this._targetType); //Cast to the source type
-
- setIL.Emit(OpCodes.Ldarg_2); //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(paramType.IsValueType)
{
- setIL.Emit(OpCodes.Unbox, paramType); //Unbox it
- if(_typeToOpcode[paramType]!=null) //and load
+ setIL.Emit(OpCodes.Unbox, paramType); //Unbox it
+ if(_typeToOpcode[paramType]!=null)
{
OpCode load = (OpCode)_typeToOpcode[paramType];
- setIL.Emit(load);
+ setIL.Emit(load); //and load
}
else
{
@@ -274,11 +315,9 @@
}
else
{
- setIL.Emit(OpCodes.Castclass, paramType); //Cast class
+ setIL.Emit(OpCodes.Castclass, paramType); //Cast class
}
-
- setIL.EmitCall(OpCodes.Callvirt,
- targetSetMethod, null); //Set the property value
+ setIL.EmitCall(OpCodes.Callvirt, targetSetMethod, null); //Set the property value
}
else
{
@@ -289,5 +328,6 @@
// Load the type
typeBuilder.CreateType();
}
+
}
}
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=387044&r1=387043&r2=387044&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 Sun Mar 19 14:02:00 2006
@@ -75,7 +75,7 @@
else
{
_createPropertyAccessor = new CreateMemberPropertyAccessor(CreateEmitPropertyAccessor);
- _createFieldAccessor = new CreateMemberFieldAccessor(CreateEmitFieldAccessor);
+ _createFieldAccessor = new CreateMemberFieldAccessor(CreateReflectionFieldAccessor);//CreateEmitFieldAccessor
}
}
else
@@ -118,7 +118,7 @@
else
{
// Field
- FieldInfo fieldInfo = targetType.GetField(name);
+ FieldInfo fieldInfo = targetType.GetField(name, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);
if (fieldInfo!=null)
{
Modified: ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/ReflectionFieldAccessor.cs
URL: http://svn.apache.org/viewcvs/ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/ReflectionFieldAccessor.cs?rev=387044&r1=387043&r2=387044&view=diff
==============================================================================
--- ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/ReflectionFieldAccessor.cs (original)
+++ ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/ReflectionFieldAccessor.cs Sun Mar 19 14:02:00 2006
@@ -24,6 +24,7 @@
#endregion
using System;
+using System.Reflection;
namespace IBatisNet.Common.Utilities.Objects.Members
{
@@ -33,6 +34,8 @@
/// </summary>
public class ReflectionFieldAccessor : IMemberAccessor
{
+ private FieldInfo _fieldInfo = null;
+
/// <summary>
/// Creates a new Reflection field accessor.
/// </summary>
@@ -40,9 +43,7 @@
/// <param name="fieldName">Field name.</param>
public ReflectionFieldAccessor(Type targetType, string fieldName)
{
- //
- // TODO: Add constructor logic here
- //
+ _fieldInfo = targetType.GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);
}
#region IMemberAccessor Members
@@ -55,8 +56,7 @@
/// <returns>Property value.</returns>
public object Get(object target)
{
- // TODO: Add ReflectionFieldAccessor.Get implementation
- return null;
+ return _fieldInfo.GetValue(target);
}
/// <summary>
@@ -67,7 +67,7 @@
/// <param name="value">Property value.</param>
public void Set(object target, object value)
{
- // TODO: Add ReflectionFieldAccessor.Set implementation
+ _fieldInfo.SetValue(target, value);
}
#endregion
Modified: ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/ReflectionPropertyAccessor.cs
URL: http://svn.apache.org/viewcvs/ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/ReflectionPropertyAccessor.cs?rev=387044&r1=387043&r2=387044&view=diff
==============================================================================
--- ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/ReflectionPropertyAccessor.cs (original)
+++ ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/ReflectionPropertyAccessor.cs Sun Mar 19 14:02:00 2006
@@ -24,6 +24,7 @@
#endregion
using System;
+using System.Reflection;
namespace IBatisNet.Common.Utilities.Objects.Members
{
@@ -33,6 +34,14 @@
/// </summary>
public class ReflectionPropertyAccessor : IMemberAccessor
{
+// private static BindingFlags BINDING_FLAGS
+// = BindingFlags.Public
+// | BindingFlags.Instance
+// ;
+
+ private PropertyInfo _propertyInfo = null;
+ private string _propertyName = string.Empty;
+ private Type _targetType = null;
/// <summary>
/// Creates a new Reflection property accessor.
@@ -41,6 +50,10 @@
/// <param name="propertyName">Property name.</param>
public ReflectionPropertyAccessor(Type targetType, string propertyName)
{
+ _propertyInfo = ObjectProbe.GetPropertyInfoForSetter(targetType, propertyName);
+ //targetType.GetProperty(propertyName, BINDING_FLAGS);
+ _targetType = targetType;
+ _propertyName = propertyName;
}
#region IMemberAccessor Members
@@ -52,8 +65,17 @@
/// <returns>Property value.</returns>
public object Get(object target)
{
- return null;
- }
+ if (_propertyInfo.CanRead)
+ {
+ return _propertyInfo.GetValue(target, null);
+ }
+ else
+ {
+ throw new MissingMethodException(
+ string.Format("Property \"{0}\" on type "
+ + "{1} doesn't have a get method.", _propertyName, _targetType));
+ }
+ }
/// <summary>
/// Sets the value for the property of
@@ -63,6 +85,16 @@
/// <param name="value">Property value.</param>
public void Set(object target, object value)
{
+ if (_propertyInfo.CanWrite)
+ {
+ _propertyInfo.SetValue(target, value, null);
+ }
+ else
+ {
+ throw new MissingMethodException(
+ string.Format("Property \"{0}\" on type "
+ + "{1} doesn't have a set method.", _propertyName, _targetType));
+ }
}
#endregion
}