Author: gbayon
Date: Wed Mar 22 13:39:21 2006
New Revision: 387952
URL: http://svn.apache.org/viewcvs?rev=387952&view=rev
Log:
- Updated IMemberAccessor support
Added:
ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/IMemberAccessorFactory.cs
(with props)
Modified:
ibatis/trunk/cs/mapper/IBatisNet.Common.Test/NUnit/CommonTests/Utilities/BaseMemberTest.cs
ibatis/trunk/cs/mapper/IBatisNet.Common/IBatisNet.Common.2005.csproj
ibatis/trunk/cs/mapper/IBatisNet.Common/IBatisNet.Common.csproj
ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/BaseEmitAccessor.cs
ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/EmitFieldAccessor.cs
ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/EmitPropertyAccessor.cs
ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/IMemberAccessor.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/NUnit/CommonTests/Utilities/BaseMemberTest.cs
URL:
http://svn.apache.org/viewcvs/ibatis/trunk/cs/mapper/IBatisNet.Common.Test/NUnit/CommonTests/Utilities/BaseMemberTest.cs?rev=387952&r1=387951&r2=387952&view=diff
==============================================================================
---
ibatis/trunk/cs/mapper/IBatisNet.Common.Test/NUnit/CommonTests/Utilities/BaseMemberTest.cs
(original)
+++
ibatis/trunk/cs/mapper/IBatisNet.Common.Test/NUnit/CommonTests/Utilities/BaseMemberTest.cs
Wed Mar 22 13:39:21 2006
@@ -13,7 +13,7 @@
[TestFixture]
public abstract class BaseMemberTest
{
- protected MemberAccessorFactory factory = null;
+ protected IMemberAccessorFactory factory = null;
protected IMemberAccessor intAccessor = null;
protected IMemberAccessor longAccessor = null;
protected IMemberAccessor sbyteAccessor = null;
Modified: ibatis/trunk/cs/mapper/IBatisNet.Common/IBatisNet.Common.2005.csproj
URL:
http://svn.apache.org/viewcvs/ibatis/trunk/cs/mapper/IBatisNet.Common/IBatisNet.Common.2005.csproj?rev=387952&r1=387951&r2=387952&view=diff
==============================================================================
--- ibatis/trunk/cs/mapper/IBatisNet.Common/IBatisNet.Common.2005.csproj
(original)
+++ ibatis/trunk/cs/mapper/IBatisNet.Common/IBatisNet.Common.2005.csproj Wed
Mar 22 13:39:21 2006
@@ -202,6 +202,7 @@
<Compile Include="Utilities\Objects\Members\EmitFieldAccessor.cs" />
<Compile Include="Utilities\Objects\Members\EmitPropertyAccessor.cs" />
<Compile Include="Utilities\Objects\Members\IMemberAccessor.cs" />
+ <Compile Include="Utilities\Objects\Members\IMemberAccessorFactory.cs" />
<Compile Include="Utilities\Objects\Members\IPropertyAccessor.cs" />
<Compile Include="Utilities\Objects\Members\MemberAccessorFactory.cs" />
<Compile Include="Utilities\Objects\Members\ReflectionFieldAccessor.cs" />
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=387952&r1=387951&r2=387952&view=diff
==============================================================================
--- ibatis/trunk/cs/mapper/IBatisNet.Common/IBatisNet.Common.csproj (original)
+++ ibatis/trunk/cs/mapper/IBatisNet.Common/IBatisNet.Common.csproj Wed Mar 22
13:39:21 2006
@@ -365,6 +365,11 @@
BuildAction = "Compile"
/>
<File
+ RelPath =
"Utilities\Objects\Members\IMemberAccessorFactory.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
RelPath = "Utilities\Objects\Members\IPropertyAccessor.cs"
SubType = "Code"
BuildAction = "Compile"
Modified:
ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/BaseEmitAccessor.cs
URL:
http://svn.apache.org/viewcvs/ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/BaseEmitAccessor.cs?rev=387952&r1=387951&r2=387952&view=diff
==============================================================================
---
ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/BaseEmitAccessor.cs
(original)
+++
ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/BaseEmitAccessor.cs
Wed Mar 22 13:39:21 2006
@@ -30,149 +30,165 @@
namespace IBatisNet.Common.Utilities.Objects.Members
{
- /// <summary>
- ///
- /// </summary>
- public abstract class BaseEmitAccessor : IMemberAccessor
- {
- /// <summary>
- /// The class parent type
- /// </summary>
- protected Type targetType = null;
- /// <summary>
- /// The property/field name
- /// </summary>
- protected string memberName = string.Empty;
- /// <summary>
- /// The property/field type
- /// </summary>
- protected Type memberType = null;
- /// <summary>
- /// The IL emitted IMemberAccessor
- /// </summary>
- protected IMemberAccessor emittedMemberAccessor = null;
- /// <summary>
- /// The AssemblyBuilder use to keep the type
- /// </summary>
- protected AssemblyBuilder assemblyBuilder = null;
- /// <summary>
- /// The ModuleBuilder use to create the type
- /// </summary>
- protected ModuleBuilder moduleBuilder = null;
- /// <summary>
- /// The null internal value used by this member type
- /// </summary>
- protected object nullInternal = null;
-
- /// <summary>
- ///
- /// </summary>
- protected static IDictionary typeToOpcode = new HybridDictionary();
+ /// <summary>
+ ///
+ /// </summary>
+ public abstract class BaseEmitAccessor : IMemberAccessor
+ {
+ /// <summary>
+ /// The class parent type
+ /// </summary>
+ protected Type targetType = null;
+ /// <summary>
+ /// The property/field name
+ /// </summary>
+ protected string memberName = string.Empty;
+ /// <summary>
+ /// The property/field type
+ /// </summary>
+ protected Type baseMemberType = null;
+ /// <summary>
+ /// The IL emitted IMemberAccessor
+ /// </summary>
+ protected IMemberAccessor emittedMemberAccessor = null;
+ /// <summary>
+ /// The AssemblyBuilder use to keep the type
+ /// </summary>
+ protected AssemblyBuilder assemblyBuilder = null;
+ /// <summary>
+ /// The ModuleBuilder use to create the type
+ /// </summary>
+ protected ModuleBuilder moduleBuilder = null;
+ /// <summary>
+ /// The null internal value used by this member type
+ /// </summary>
+ protected object nullInternal = null;
+
+ /// <summary>
+ ///
+ /// </summary>
+ protected static IDictionary typeToOpcode = new
HybridDictionary();
/// <summary>
/// Static constructor
- /// "Initialize a private IDictionary with type-opCode pairs
+ /// "Initialize a private IDictionary with type-opCode pairs
/// </summary>
- static BaseEmitAccessor()
+ static BaseEmitAccessor()
{
- 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;
+ 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>
+ /// Get the null value for a given type
+ /// </summary>
+ /// <param name="type"></param>
+ /// <returns></returns>
+ protected 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>
- /// Get the null value for a given type
- /// </summary>
- /// <param name="type"></param>
- /// <returns></returns>
- protected 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 create a new type oject for the the field accessor
class
- /// that will provide dynamic access.
- /// </summary>
- protected void EmitIL()
- {
- // Create a new type oject for the the field accessor class.
- EmitType();
-
- // Create a new instance
- emittedMemberAccessor =
assemblyBuilder.CreateInstance("MemberAccessorFor" + targetType.FullName +
memberName) as IMemberAccessor;
-
- nullInternal = GetNullInternal(memberType);
-
- if (emittedMemberAccessor == null)
- {
- throw new MethodAccessException(
- string.Format("Unable to create propert/field accessor for
\"{0}\".", memberType));
- }
- }
+ /// <summary>
+ /// This method create a new type oject for the the field
accessor class
+ /// that will provide dynamic access.
+ /// </summary>
+ protected void EmitIL()
+ {
+ // Create a new type oject for the the field accessor
class.
+ EmitType();
+
+ // Create a new instance
+ emittedMemberAccessor =
assemblyBuilder.CreateInstance("MemberAccessorFor" + targetType.FullName +
memberName) as IMemberAccessor;
+
+ nullInternal = GetNullInternal(baseMemberType);
+
+ if (emittedMemberAccessor == null)
+ {
+ throw new MethodAccessException(
+ string.Format("Unable to create
propert/field accessor for \"{0}\".", baseMemberType));
+ }
+ }
- /// <summary>
+ /// <summary>
/// Create an type that will provide the get and set methods.
/// </summary>
- protected abstract void EmitType();
+ protected abstract void EmitType();
- #region IMemberAccessor Members
+ #region IMemberAccessor Members
- /// <summary>
- /// Gets the field value from the specified target.
- /// </summary>
- /// <param name="target">Target object.</param>
- /// <returns>Property value.</returns>
- public abstract object Get(object target);
-
- /// <summary>
- /// Sets the field for the specified target.
- /// </summary>
- /// <param name="target">Target object.</param>
- /// <param name="value">Value to set.</param>
- public abstract void Set(object target, object value);
+ /// <summary>
+ /// Gets the type of this member, such as field, property.
+ /// </summary>
+ public Type MemberType
+ {
+ get { return baseMemberType; }
+ }
+
+ /// <summary>
+ /// Gets the member name.
+ /// </summary>
+ public string Name
+ {
+ get { return memberName; }
+ }
+
+ /// <summary>
+ /// Gets the field value from the specified target.
+ /// </summary>
+ /// <param name="target">Target object.</param>
+ /// <returns>Property value.</returns>
+ public abstract object Get(object target);
+
+ /// <summary>
+ /// Sets the field for the specified target.
+ /// </summary>
+ /// <param name="target">Target object.</param>
+ /// <param name="value">Value to set.</param>
+ public abstract void Set(object target, object value);
- #endregion
- }
+ #endregion
+ }
}
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=387952&r1=387951&r2=387952&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
Wed Mar 22 13:39:21 2006
@@ -24,8 +24,6 @@
#endregion
using System;
-using System.Collections;
-using System.Collections.Specialized;
using System.Reflection;
using System.Reflection.Emit;
@@ -36,21 +34,21 @@
/// to a field of a specified target class.
/// </summary>
/// <remarks>Will Throw FieldAccessException on private field</remarks>
- public sealed class EmitFieldAccessor : BaseEmitAccessor
+ public sealed class EmitFieldAccessor : BaseEmitAccessor
{
/// <summary>
/// Creates a new IL field accessor.
/// </summary>
- /// <param name="targetObjectType">Target object type.</param>
+ /// <param name="targetObjectType">Target object type.</param>
/// <param name="fieldName">Field name.</param>
- /// <param name="assemBuilder"></param>
- /// <param name="modBuilder"></param>
+ /// <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;
+ assemblyBuilder = assemBuilder;
+ moduleBuilder = modBuilder;
+ targetType = targetObjectType;
+ memberName = fieldName;
FieldInfo fieldInfo = targetType.GetField(fieldName,
BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);
@@ -59,101 +57,148 @@
{
throw new MissingMethodException(
string.Format("Field \"{0}\" does not
exist for type "
- + "{1}.", fieldName, targetObjectType));
+ + "{1}.", fieldName, targetObjectType));
}
else
{
- memberType = fieldInfo.FieldType;
+ baseMemberType = fieldInfo.FieldType;
this.EmitIL();
}
}
-
+
+ private void ImplementProperty(TypeBuilder type, FieldBuilder
field, PropertyInfo prop)
+ {
+ MethodBuilder getter = type.DefineMethod("get_" +
prop.Name, MethodAttributes.Public | MethodAttributes.Virtual |
MethodAttributes.HideBySig | MethodAttributes.SpecialName, prop.PropertyType,
null);
+ type.DefineMethodOverride(getter, prop.GetGetMethod());
+ ILGenerator getterIL = getter.GetILGenerator();
+ getterIL.Emit(OpCodes.Ldarg_0);
+ getterIL.Emit(OpCodes.Ldfld, field);
+ getterIL.Emit(OpCodes.Ret);
+ }
+
/// <summary>
/// Create an type that will provide the get and set methods.
/// </summary>
- protected override void EmitType()
+ protected override void EmitType()
{
// Define a public class named
"FieldAccessorFor.FullTagetTypeName.FieldName" in the assembly.
- TypeBuilder typeBuilder =
moduleBuilder.DefineType("MemberAccessorFor" + targetType.FullName +
memberName, 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));
- // Add a constructor
-
typeBuilder.DefineDefaultConstructor(MethodAttributes.Public);
+ // Define 2 private fields
+ FieldBuilder fieldBuilderMemberType =
typeBuilder.DefineField("_memberType",
+ typeof(Type),
+ FieldAttributes.Private);
+
+ FieldBuilder fieldBuilderName =
typeBuilder.DefineField("_name",
+ typeof(Type),
+ FieldAttributes.Private);
+
+ #region Emit constructor
+ // Create a new constructor (public)
+ ConstructorBuilder cb =
typeBuilder.DefineConstructor(MethodAttributes.Public,
+ CallingConventions.Standard, Type.EmptyTypes);
+ // Get the constructor's IL generator
+ ILGenerator constructorIL = cb.GetILGenerator();
+
+ // Load "this"
+ constructorIL.Emit(OpCodes.Ldarg_0);
+ // Call the base constructor (no args)
+ constructorIL.Emit(OpCodes.Call,
typeof(Object).GetConstructor(Type.EmptyTypes));
+ // // Load "this"
+ // constructorIL.Emit(OpCodes.Ldarg_0);
+ // // Load member type
+ // constructorIL.Emit(OpCodes.Call,
baseMemberType.GetType());
+ // // Store in field "_memberType"
+ // constructorIL.Emit(OpCodes.Stfld,
fieldBuilder);
+ // Emit return opcode
+ constructorIL.Emit(OpCodes.Ret);
+ #endregion
+
+ PropertyInfo prop
=typeof(IMemberAccessor).GetProperty("MemberType");
+ ImplementProperty(typeBuilder, fieldBuilderMemberType,
prop);
+ prop =typeof(IMemberAccessor).GetProperty("Name");
+ ImplementProperty(typeBuilder, fieldBuilderName, prop);
+
+ #region Emit Get
// Define a method named "Get" for the get operation
(IMemberAccessor).
- Type[] getParamTypes = new Type[] {typeof(object)};
- MethodBuilder getMethod =
typeBuilder.DefineMethod("Get",
+ Type[] getParamTypes = new Type[] { typeof(object) };
+ MethodBuilder getMethod =
typeBuilder.DefineMethod("Get",
MethodAttributes.Public |
MethodAttributes.Virtual,
- typeof(object),
+ typeof(object),
getParamTypes);
// Get an ILGenerator and used it to emit the IL that
we want.
ILGenerator getIL = getMethod.GetILGenerator();
- FieldInfo targetField = targetType.GetField(memberName,
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)
+ 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);
+ // 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.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);
- }
+ if (baseMemberType.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
{
getIL.ThrowException(typeof(MissingMethodException));
}
- getIL.Emit(OpCodes.Ret);
+ getIL.Emit(OpCodes.Ret);
+ #endregion
+ #region Emit Set
// 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,
+ 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)
+ if (targetField != null)
{
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 (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
- }
+ if (baseMemberType.IsValueType)
+ {
+ setIL.Emit(OpCodes.Unbox,
baseMemberType); //Unbox it
+ if (typeToOpcode[baseMemberType] !=
null)
+ {
+ OpCode load =
(OpCode)typeToOpcode[baseMemberType];
+ setIL.Emit(load); //and load
+ }
+ else
+ {
+ setIL.Emit(OpCodes.Ldobj,
baseMemberType);
+ }
+ }
+ else
+ {
+ setIL.Emit(OpCodes.Castclass,
baseMemberType); //Cast class
+ }
setIL.Emit(OpCodes.Stfld, targetField); //Set
the field value
}
else
{
setIL.ThrowException(typeof(MissingMethodException));
}
- setIL.Emit(OpCodes.Ret);
+ setIL.Emit(OpCodes.Ret);
+ #endregion
// Load the type
typeBuilder.CreateType();
@@ -167,9 +212,9 @@
/// </summary>
/// <param name="target">Target object.</param>
/// <returns>Property value.</returns>
- public override object Get(object target)
+ public override object Get(object target)
{
- return emittedMemberAccessor.Get(target);
+ return emittedMemberAccessor.Get(target);
}
/// <summary>
@@ -177,7 +222,7 @@
/// </summary>
/// <param name="target">Target object.</param>
/// <param name="value">Value to set.</param>
- public override void Set(object target, object value)
+ public override void Set(object target, object value)
{
object newValue = value;
if (newValue == null)
@@ -185,7 +230,7 @@
// If the value to assign is null, assign null
internal value
newValue = nullInternal;
}
- emittedMemberAccessor.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=387952&r1=387951&r2=387952&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
Wed Mar 22 13:39:21 2006
@@ -24,22 +24,21 @@
#endregion
using System;
-using System.Collections;
-using System.Collections.Specialized;
using System.Reflection;
using System.Reflection.Emit;
namespace IBatisNet.Common.Utilities.Objects.Members
{
- /// <summary>
- /// The EmitPropertyAccessor class provides an IL-based access
- /// to a property of a specified target class.
- /// </summary>
- public sealed class EmitPropertyAccessor : BaseEmitAccessor,
IPropertyAccessor
+ /// <summary>
+ /// The EmitPropertyAccessor class provides an IL-based access
+ /// to a property of a specified target class.
+ /// </summary>
+ public sealed class EmitPropertyAccessor : BaseEmitAccessor,
IPropertyAccessor
{
private bool _canRead = false;
private bool _canWrite = false;
+ #region IPropertyAccessor
/// <summary>
/// Gets a value indicating whether the property can be read.
/// </summary>
@@ -55,20 +54,21 @@
{
get { return _canWrite; }
}
-
+ #endregion
+
/// <summary>
/// Creates a new IL property accessor.
/// </summary>
- /// <param name="targetObjectType">Target object type.</param>
- /// <param name="propertyName">Property name.</param>
- /// <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;
+ /// <param name="targetObjectType">Target object type.</param>
+ /// <param name="propertyName">Property name.</param>
+ /// <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);
@@ -77,24 +77,26 @@
{
throw new MissingMethodException(
string.Format("Property \"{0}\" does
not exist for type "
- + "{1}.", propertyName, targetType));
+ + "{1}.", propertyName, targetType));
}
else
{
- memberType = propertyInfo.PropertyType;
+ baseMemberType = propertyInfo.PropertyType;
_canRead = propertyInfo.CanRead;
_canWrite = propertyInfo.CanWrite;
- this.EmitIL();
+ this.EmitIL();
}
}
+
#region IMemberAccessor Members
+
/// <summary>
/// Gets the property value from the specified target.
/// </summary>
/// <param name="target">Target object.</param>
/// <returns>Property value.</returns>
- public override object Get(object target)
+ public override object Get(object target)
{
if (_canRead)
{
@@ -114,7 +116,7 @@
/// </summary>
/// <param name="target">Target object.</param>
/// <param name="value">Value to set.</param>
- public override void Set(object target, object value)
+ public override void Set(object target, object value)
{
if (_canWrite)
{
@@ -137,43 +139,122 @@
#endregion
-
+ private void ImplementProperty(TypeBuilder type, FieldBuilder
field, PropertyInfo prop)
+ {
+ MethodBuilder getter = type.DefineMethod("get_" +
prop.Name, MethodAttributes.Public | MethodAttributes.Virtual |
MethodAttributes.HideBySig | MethodAttributes.SpecialName, prop.PropertyType,
null);
+ type.DefineMethodOverride(getter, prop.GetGetMethod());
+ ILGenerator getterIL = getter.GetILGenerator();
+ getterIL.Emit(OpCodes.Ldarg_0);
+ getterIL.Emit(OpCodes.Ldfld, field);
+ getterIL.Emit(OpCodes.Ret);
+ }
+
/// <summary>
/// Create an type that will provide the get and set access
method.
/// </summary>
- protected override void EmitType()
+ /// <remarks>
+ /// new
ReflectionPermission(PermissionState.Unrestricted).Assert();
+ /// CodeAccessPermission.RevertAssert();
+ /// </remarks>
+ protected override void EmitType()
{
// Define a public class named
"PropertyAccessorFor.FullTagetTypeName.PropertyName" in the assembly.
- TypeBuilder typeBuilder =
moduleBuilder.DefineType("MemberAccessorFor" + targetType.FullName +
memberName, 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));
- // Add a constructor
-
typeBuilder.DefineDefaultConstructor(MethodAttributes.Public);
+ // Define 2 private fields
+ FieldBuilder fieldBuilderMemberType =
typeBuilder.DefineField("_memberType",
+ typeof(Type),
+ FieldAttributes.Private);
+
+ FieldBuilder fieldBuilderName =
typeBuilder.DefineField("_name",
+ typeof(string),
+ FieldAttributes.Private);
+
+ #region Emit constructor
+ // Create a new constructor (public)
+ ConstructorBuilder cb =
typeBuilder.DefineConstructor(MethodAttributes.Public,
+ CallingConventions.Standard, Type.EmptyTypes);
+ // Get the constructor's IL generator
+ ILGenerator constructorIL = cb.GetILGenerator();
+
+ // Load "this"
+ constructorIL.Emit(OpCodes.Ldarg_0);
+ // Call the base constructor (no args)
+ constructorIL.Emit(OpCodes.Call,
typeof(object).GetConstructor(Type.EmptyTypes));
+ // Load "this"
+ constructorIL.Emit(OpCodes.Ldarg_0);
+ // Store name in field "_name"
+ constructorIL.Emit(OpCodes.Ldstr, memberName);
+ constructorIL.Emit(OpCodes.Stfld, fieldBuilderName);
+ // Store type in field "_memberType"
+ //
constructorIL.Emit(OpCodes.Ldtoken, baseMemberType);
+ // MethodInfo miGetTypeFromHandle
= typeof(System.Type).GetMethod("GetTypeFromHandle", new Type[]
{typeof(System.RuntimeTypeHandle)});
+ //
constructorIL.EmitCall(OpCodes.Call, miGetTypeFromHandle, null);
+ //
constructorIL.Emit(OpCodes.Stfld, fieldBuilderMemberType);
+ // Emit return opcode
+ constructorIL.Emit(OpCodes.Ret);
+ #endregion
+
+ PropertyInfo prop
=typeof(IMemberAccessor).GetProperty("MemberType");
+ ImplementProperty(typeBuilder, fieldBuilderMemberType,
prop);
+
+ prop =typeof(IMemberAccessor).GetProperty("Name");
+ ImplementProperty(typeBuilder, fieldBuilderName, prop);
+
+ // #region Emit MemberType
+ // // Define the property MemberType
(IMemberAccessor).
+ // PropertyBuilder propertyBuilder =
typeBuilder.DefineProperty("MemberType",
+ // PropertyAttributes.None,
+ // typeof(Type),
+ // new Type[] {
typeof(Type) });
+ //
+ // // Define the get method for
the property for MemberType
+ // MethodBuilder getMethodBuilder =
typeBuilder.DefineMethod("get_MemberType",
+ //
MethodAttributes.Public | MethodAttributes.Virtual ,
+ // typeof(Type),
+ // Type.EmptyTypes);
+ //
typeBuilder.DefineMethodOverride(getMethodBuilder,
typeof(IMemberAccessor).GetProperty("MemberType").GetGetMethod());
+ //
+ // // Get an ILGenerator and used it to emit
the IL that we want.
+ // ILGenerator getMethod =
getMethodBuilder.GetILGenerator();
+ //
+ // // Emit the IL for get access.
+ // getMethod.Emit(OpCodes.Ldarg_0);
+ // getMethod.Emit(OpCodes.Ldfld,
fieldBuilder);
+ // getMethod.Emit(OpCodes.Ret);
+ //
+ // // Last, we must map the method created
above to our PropertyBuilder to
+ // // the corresponding behavior "get".
+ //
propertyBuilder.SetGetMethod(getMethodBuilder);
+ //
+ //
+ // #endregion
+ #region Emit Get
// Define a method named "Get" for the get operation
(IMemberAccessor).
- Type[] getParamTypes = new Type[] {typeof(object)};
- MethodBuilder getMethod =
- typeBuilder.DefineMethod("Get",
+ Type[] getParamTypes = new Type[] { typeof(object) };
+ MethodBuilder methodBuilder =
typeBuilder.DefineMethod("Get",
MethodAttributes.Public |
MethodAttributes.Virtual,
- typeof(object),
+ typeof(object),
getParamTypes);
// Get an ILGenerator and used it to emit the IL that
we want.
- ILGenerator getIL = getMethod.GetILGenerator();
+ ILGenerator getIL = methodBuilder.GetILGenerator();
// Emit the IL for get access.
MethodInfo targetGetMethod =
targetType.GetMethod("get_" + memberName);
- if(targetGetMethod != null)
+ 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.EmitCall(OpCodes.Call, targetGetMethod,
null); //Get the property value
- if(targetGetMethod.ReturnType.IsValueType)
+ if (targetGetMethod.ReturnType.IsValueType)
{
getIL.Emit(OpCodes.Box,
targetGetMethod.ReturnType); //Box if necessary
}
@@ -185,39 +266,39 @@
getIL.ThrowException(typeof(MissingMethodException));
}
getIL.Emit(OpCodes.Ret);
+ #endregion
-
+ #region Emit Set
// 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,
+ Type[] setParamTypes = new Type[] { typeof(object),
typeof(object) };
+ methodBuilder = typeBuilder.DefineMethod("Set",
+ MethodAttributes.Public |
MethodAttributes.Virtual,
+ null,
setParamTypes);
// Get an ILGenerator and used to emit the IL that we
want.
- // Set(object, value);
- ILGenerator setIL = setMethod.GetILGenerator();
+ // Set(object, value);
+ ILGenerator setIL = methodBuilder.GetILGenerator();
// Emit the IL for the set access.
MethodInfo targetSetMethod =
targetType.GetMethod("set_" + memberName);
- if(targetSetMethod != null)
+ 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.Ldarg_2); //Load the second
argument (value object)
- if(paramType.IsValueType)
+ if (paramType.IsValueType)
{
setIL.Emit(OpCodes.Unbox, paramType);
//Unbox it
- if(typeToOpcode[paramType]!=null)
+ if (typeToOpcode[paramType] != null)
{
OpCode load =
(OpCode)typeToOpcode[paramType];
setIL.Emit(load); //and load
}
else
{
-
setIL.Emit(OpCodes.Ldobj,paramType);
+ setIL.Emit(OpCodes.Ldobj,
paramType);
}
}
else
@@ -230,7 +311,8 @@
{
setIL.ThrowException(typeof(MissingMethodException));
}
- setIL.Emit(OpCodes.Ret);
+ setIL.Emit(OpCodes.Ret);
+ #endregion
// Load the type
typeBuilder.CreateType();
Modified:
ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/IMemberAccessor.cs
URL:
http://svn.apache.org/viewcvs/ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/IMemberAccessor.cs?rev=387952&r1=387951&r2=387952&view=diff
==============================================================================
---
ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/IMemberAccessor.cs
(original)
+++
ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/IMemberAccessor.cs
Wed Mar 22 13:39:21 2006
@@ -23,28 +23,37 @@
********************************************************************************/
#endregion
+using System;
+
namespace IBatisNet.Common.Utilities.Objects.Members
{
/// <summary>
- /// The IMemberAccessor interface defines a field/property
- /// accessor.
+ /// The IMemberAccessor interface defines a field/property accessor.
/// </summary>
public interface IMemberAccessor
{
/// <summary>
- /// Gets the value stored in the property for
- /// the specified target.
+ /// Gets the member name.
+ /// </summary>
+ string Name { get; }
+
+ /// <summary>
+ /// Gets the type of this member (field or property).
+ /// </summary>
+ Type MemberType { get; }
+
+ /// <summary>
+ /// Gets the value stored in the field/property for the
specified target.
/// </summary>
/// <param name="target">Object to retrieve the field/property
from.</param>
- /// <returns>Property value.</returns>
+ /// <returns>Value.</returns>
object Get(object target);
/// <summary>
- /// Sets the value for the property of
- /// the specified target.
+ /// Sets the value for the field/property of the specified
target.
/// </summary>
/// <param name="target">Object to set the field/property
on.</param>
- /// <param name="value">Property value.</param>
+ /// <param name="value">Value.</param>
void Set(object target, object value);
}
}
Added:
ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/IMemberAccessorFactory.cs
URL:
http://svn.apache.org/viewcvs/ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/IMemberAccessorFactory.cs?rev=387952&view=auto
==============================================================================
---
ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/IMemberAccessorFactory.cs
(added)
+++
ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/IMemberAccessorFactory.cs
Wed Mar 22 13:39:21 2006
@@ -0,0 +1,43 @@
+#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;
+
+namespace IBatisNet.Common.Utilities.Objects.Members
+{
+ /// <summary>
+ /// Factory contact to build IMemberAccessor for a type.
+ /// </summary>
+ public interface IMemberAccessorFactory
+ {
+ /// <summary>
+ /// Generate an IMemberAccessor object
+ /// </summary>
+ /// <param name="targetType">Target object type.</param>
+ /// <param name="name">Field or Property name.</param>
+ /// <returns>null if the generation fail</returns>
+ IMemberAccessor CreateMemberAccessor(Type targetType, string
name);
+ }
+}
\ No newline at end of file
Propchange:
ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/IMemberAccessorFactory.cs
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Objects/Members/IMemberAccessorFactory.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=387952&r1=387951&r2=387952&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
Wed Mar 22 13:39:21 2006
@@ -35,7 +35,7 @@
/// <summary>
/// A factory to build IMemberAccessor for a type.
/// </summary>
- public class MemberAccessorFactory
+ public class MemberAccessorFactory : IMemberAccessorFactory
{
private delegate IMemberAccessor
CreateMemberPropertyAccessor(Type targetType, string propertyName);
private delegate IMemberAccessor CreateMemberFieldAccessor(Type
targetType, string fieldName);
@@ -46,7 +46,7 @@
private IDictionary _cachedIMemberAccessor = new
HybridDictionary();
private AssemblyBuilder _assemblyBuilder = null;
private ModuleBuilder _moduleBuilder = null;
- private object _padlock = new object();
+ private object _syncObject = new object();
/// <summary>
/// Constructor
@@ -87,7 +87,7 @@
}
/// <summary>
- /// Generate an IPropertyAccessor object
+ /// Generate an IMemberAccessor object
/// </summary>
/// <param name="targetType">Target object type.</param>
/// <param name="name">Field or Property name.</param>
@@ -103,7 +103,7 @@
else
{
IMemberAccessor memberAccessor = null;
- lock (_padlock)
+ lock (_syncObject)
{
if
(!_cachedIMemberAccessor.Contains(key))
{
@@ -144,7 +144,7 @@
/// <summary>
- /// Generate a ILPropertyAccessor object
+ /// Create a ILPropertyAccessor object
/// </summary>
/// <param name="targetType">Target object type.</param>
/// <param name="propertyName">Property name.</param>
@@ -155,7 +155,7 @@
}
/// <summary>
- /// Generate a EmitPropertyAccessor object
+ /// Create a field IMemberAccessor object
/// </summary>
/// <param name="targetType">Target object type.</param>
/// <param name="fieldName">Field name.</param>
@@ -175,7 +175,7 @@
}
/// <summary>
- /// Generate a ReflectionPropertyAccessor object
+ /// Create a ReflectionPropertyAccessor object
/// </summary>
/// <param name="targetType">Target object type.</param>
/// <param name="propertyName">Property name.</param>
@@ -186,7 +186,7 @@
}
/// <summary>
- /// Generate a ReflectionFieldAccessor object
+ /// Create a ReflectionFieldAccessor object
/// </summary>
/// <param name="targetType">Target object type.</param>
/// <param name="fieldName">field name.</param>
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=387952&r1=387951&r2=387952&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
Wed Mar 22 13:39:21 2006
@@ -49,6 +49,22 @@
#region IMemberAccessor Members
/// <summary>
+ /// Gets the member name.
+ /// </summary>
+ public string Name
+ {
+ get { return _fieldInfo.Name; }
+ }
+
+ /// <summary>
+ /// Gets the type of this member, such as field, property.
+ /// </summary>
+ public Type MemberType
+ {
+ get { return _fieldInfo.FieldType; }
+ }
+
+ /// <summary>
/// Gets the value stored in the field for
/// the specified target.
/// </summary>
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=387952&r1=387951&r2=387952&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
Wed Mar 22 13:39:21 2006
@@ -28,16 +28,16 @@
namespace IBatisNet.Common.Utilities.Objects.Members
{
- /// <summary>
- /// The ReflectionPropertyAccessor class provides an reflection access
- /// to a property of a specified target class.
- /// </summary>
- public class ReflectionPropertyAccessor : IMemberAccessor
- {
-// private static BindingFlags BINDING_FLAGS
-// = BindingFlags.Public
-// | BindingFlags.Instance
-// ;
+ /// <summary>
+ /// The ReflectionPropertyAccessor class provides an reflection access
+ /// to a property of a specified target class.
+ /// </summary>
+ public class ReflectionPropertyAccessor : IMemberAccessor,
IPropertyAccessor
+ {
+ // private static BindingFlags BINDING_FLAGS
+ // = BindingFlags.Public
+ // | BindingFlags.Instance
+ // ;
private PropertyInfo _propertyInfo = null;
private string _propertyName = string.Empty;
@@ -51,20 +51,55 @@
public ReflectionPropertyAccessor(Type targetType, string
propertyName)
{
_propertyInfo =
ObjectProbe.GetPropertyInfoForSetter(targetType, propertyName);
- //targetType.GetProperty(propertyName,
BINDING_FLAGS);
+ //targetType.GetProperty(propertyName, BINDING_FLAGS);
_targetType = targetType;
_propertyName = propertyName;
}
+ #region IPropertyAccessor
+ /// <summary>
+ /// Gets a value indicating whether the property can be read.
+ /// </summary>
+ public bool CanRead
+ {
+ get { return _propertyInfo.CanRead; }
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether the property can be written
to.
+ /// </summary>
+ public bool CanWrite
+ {
+ get { return _propertyInfo.CanWrite; }
+ }
+ #endregion
+
#region IMemberAccessor Members
- /// <summary>
- /// Gets the value stored in the property for
- /// the specified target.
- /// </summary>
- /// <param name="target">Object to retrieve the property from.</param>
- /// <returns>Property value.</returns>
- public object Get(object target)
- {
+
+ /// <summary>
+ /// Gets the member name.
+ /// </summary>
+ public string Name
+ {
+ get { return _propertyInfo.Name; }
+ }
+
+ /// <summary>
+ /// Gets the type of this member, such as field, property.
+ /// </summary>
+ public Type MemberType
+ {
+ get { return _propertyInfo.PropertyType; }
+ }
+
+ /// <summary>
+ /// Gets the value stored in the property for
+ /// the specified target.
+ /// </summary>
+ /// <param name="target">Object to retrieve the property
from.</param>
+ /// <returns>Property value.</returns>
+ public object Get(object target)
+ {
if (_propertyInfo.CanRead)
{
return _propertyInfo.GetValue(target, null);
@@ -77,14 +112,14 @@
}
}
- /// <summary>
- /// Sets the value for the property of
- /// the specified target.
- /// </summary>
- /// <param name="target">Object to set the property on.</param>
- /// <param name="value">Property value.</param>
- public void Set(object target, object value)
- {
+ /// <summary>
+ /// Sets the value for the property of
+ /// the specified target.
+ /// </summary>
+ /// <param name="target">Object to set the property on.</param>
+ /// <param name="value">Property value.</param>
+ public void Set(object target, object value)
+ {
if (_propertyInfo.CanWrite)
{
_propertyInfo.SetValue(target, value, null);
@@ -95,7 +130,7 @@
string.Format("Property \"{0}\" on type
"
+ "{1} doesn't have a set method.",
_propertyName, _targetType));
}
- }
+ }
#endregion
- }
+ }
}