Update of /cvsroot/springnet/Spring.Net/src/Spring/Spring.Core/Reflection/Dynamic
In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv5374/src/Spring/Spring.Core/Reflection/Dynamic
Modified Files:
DynamicField.cs DynamicProperty.cs DynamicReflectionManager.cs
Log Message:
added System.Reflection.Emit.DynamicMethod support to DynamicReflectionManager
migrated DynamicField and DynamicProperty to DynamicMethd
Index: DynamicReflectionManager.cs
===================================================================
RCS file: /cvsroot/springnet/Spring.Net/src/Spring/Spring.Core/Reflection/Dynamic/DynamicReflectionManager.cs,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** DynamicReflectionManager.cs 27 Aug 2007 15:18:43 -0000 1.2
--- DynamicReflectionManager.cs 13 May 2008 23:23:03 -0000 1.3
***************
*** 28,31 ****
--- 28,35 ----
using Spring.Util;
+ #if NET_2_0
+ using NetDynamicMethod = System.Reflection.Emit.DynamicMethod;
+ #endif
+
#endregion
***************
*** 33,36 ****
--- 37,62 ----
{
/// <summary>
+ /// Represents a Get method
+ /// </summary>
+ /// <param name="target">the target instance when calling an instance method</param>
+ /// <returns>the value return by the Get method</returns>
+ public delegate object GetterDelegate(object target);
+
+ /// <summary>
+ /// Represents a Set method
+ /// </summary>
+ /// <param name="target">the target instance when calling an instance method</param>
+ /// <param name="value">the value to be set</param>
+ public delegate void SetterDelegate(object target, object value);
+
+ /// <summary>
+ /// Represents a method
+ /// </summary>
+ /// <param name="target">the target instance when calling an instance method</param>
+ /// <param name="args">arguments to be passed to the method</param>
+ /// <returns>the value return by the method. <value>null</value> when calling a void method</returns>
+ public delegate object FunctionDelegate(object target, params object[] args);
+
+ /// <summary>
/// Represents a callback method used to create an <see cref="IDynamicProperty"/> from a <see cref="PropertyInfo"/> instance.
/// </summary>
***************
*** 53,61 ****
internal delegate IDynamicIndexer CreateIndexerCallback(PropertyInfo indexer);
! /// <summary>
/// Allows easy access to existing and creation of new dynamic relection members.
! /// </summary>
/// <author>Aleksandar Seovic</author>
! /// <version>$Id$</version>
public sealed class DynamicReflectionManager
{
--- 79,87 ----
internal delegate IDynamicIndexer CreateIndexerCallback(PropertyInfo indexer);
! /// <summary>
/// Allows easy access to existing and creation of new dynamic relection members.
! /// </summary>
/// <author>Aleksandar Seovic</author>
! /// <version>$Id$</version>
public sealed class DynamicReflectionManager
{
***************
*** 66,70 ****
/// </summary>
public const string ASSEMBLY_NAME = "Spring.DynamicReflection";
!
/// <summary>
/// The attributes of the reflection type to generate.
--- 92,96 ----
/// </summary>
public const string ASSEMBLY_NAME = "Spring.DynamicReflection";
!
/// <summary>
/// The attributes of the reflection type to generate.
***************
*** 75,79 ****
/// Cache for dynamic property types.
/// </summary>
! private readonly static IDictionary propertyCache = new Hashtable();
/// <summary>
--- 101,105 ----
/// Cache for dynamic property types.
/// </summary>
! private readonly static IDictionary propertyCache = new Hashtable();
/// <summary>
***************
*** 87,91 ****
private readonly static IDictionary indexerCache = new Hashtable();
! /// <summary>
/// Cache for dynamic method types.
/// </summary>
--- 113,117 ----
private readonly static IDictionary indexerCache = new Hashtable();
! /// <summary>
/// Cache for dynamic method types.
/// </summary>
***************
*** 96,101 ****
/// </summary>
private readonly static IDictionary constructorCache = new Hashtable();
!
! #endregion
#region Public Methods
--- 122,127 ----
/// </summary>
private readonly static IDictionary constructorCache = new Hashtable();
!
! #endregion
#region Public Methods
***************
*** 108,112 ****
/// </param>
/// <returns>The type builder to use.</returns>
! public static TypeBuilder CreateTypeBuilder(string name)
{
// Generates type name
--- 134,138 ----
/// </param>
/// <returns>The type builder to use.</returns>
! internal static TypeBuilder CreateTypeBuilder(string name)
{
// Generates type name
***************
*** 118,133 ****
}
! /// <summary>
! /// Returns dynamic property if one exists.
! /// </summary>
! /// <param name="property">Property to look up.</param>
! /// <param name="createCallback">callback function that will be called to create the dynamic property</param>
! /// <returns>An <see cref="IDynamicProperty"/> for the given property info.</returns>
internal static IDynamicProperty GetDynamicProperty(PropertyInfo property, CreatePropertyCallback createCallback)
{
lock (propertyCache.SyncRoot)
{
! IDynamicProperty dynamicProperty = (IDynamicProperty) propertyCache[property];
! if (dynamicProperty==null)
{
dynamicProperty = createCallback(property);
--- 144,159 ----
}
! /// <summary>
! /// Returns dynamic property if one exists.
! /// </summary>
! /// <param name="property">Property to look up.</param>
! /// <param name="createCallback">callback function that will be called to create the dynamic property</param>
! /// <returns>An <see cref="IDynamicProperty"/> for the given property info.</returns>
internal static IDynamicProperty GetDynamicProperty(PropertyInfo property, CreatePropertyCallback createCallback)
{
lock (propertyCache.SyncRoot)
{
! IDynamicProperty dynamicProperty = (IDynamicProperty)propertyCache[property];
! if (dynamicProperty == null)
{
dynamicProperty = createCallback(property);
***************
*** 148,152 ****
lock (fieldCache.SyncRoot)
{
! IDynamicField dynamicField = (IDynamicField) fieldCache[field];
if (dynamicField == null)
{
--- 174,178 ----
lock (fieldCache.SyncRoot)
{
! IDynamicField dynamicField = (IDynamicField)fieldCache[field];
if (dynamicField == null)
{
***************
*** 168,173 ****
lock (indexerCache.SyncRoot)
{
! IDynamicIndexer dynamicIndexer = (IDynamicIndexer) indexerCache[indexer];
! if (dynamicIndexer==null)
{
dynamicIndexer = createCallback(indexer);
--- 194,199 ----
lock (indexerCache.SyncRoot)
{
! IDynamicIndexer dynamicIndexer = (IDynamicIndexer)indexerCache[indexer];
! if (dynamicIndexer == null)
{
dynamicIndexer = createCallback(indexer);
***************
*** 178,182 ****
}
! /// <summary>
/// Returns dynamic method if one exists.
/// </summary>
--- 204,208 ----
}
! /// <summary>
/// Returns dynamic method if one exists.
/// </summary>
***************
*** 188,193 ****
lock (methodCache.SyncRoot)
{
! IDynamicMethod dynamicMethod = (IDynamicMethod) methodCache[method];
! if (dynamicMethod==null)
{
dynamicMethod = createCallback(method);
--- 214,219 ----
lock (methodCache.SyncRoot)
{
! IDynamicMethod dynamicMethod = (IDynamicMethod)methodCache[method];
! if (dynamicMethod == null)
{
dynamicMethod = createCallback(method);
***************
*** 208,213 ****
lock (constructorCache.SyncRoot)
{
! IDynamicConstructor dynamicConstructor = (IDynamicConstructor) constructorCache[constructor];
! if (dynamicConstructor==null)
{
dynamicConstructor = createCallback(constructor);
--- 234,239 ----
lock (constructorCache.SyncRoot)
{
! IDynamicConstructor dynamicConstructor = (IDynamicConstructor)constructorCache[constructor];
! if (dynamicConstructor == null)
{
dynamicConstructor = createCallback(constructor);
***************
*** 227,232 ****
DynamicCodeManager.SaveAssembly(ASSEMBLY_NAME);
}
!
#endregion
}
}
\ No newline at end of file
--- 253,554 ----
DynamicCodeManager.SaveAssembly(ASSEMBLY_NAME);
}
!
#endregion
+
+ #if NET_2_0
+ private static readonly ConstructorInfo NewInvalidOperationException =
+ typeof(InvalidOperationException).GetConstructor(new Type[] { typeof(string) });
+
+ /// <summary>
+ /// Create a new Get method delegate for the specified field using <see cref="System.Reflection.Emit.DynamicMethod"/>
+ /// </summary>
+ /// <param name="fieldInfo">the field to create the delegate for</param>
+ /// <returns>a delegate that can be used to read the field</returns>
+ public static GetterDelegate CreateFieldGetter(FieldInfo fieldInfo)
+ {
+ AssertUtils.ArgumentNotNull(fieldInfo, "You cannot create a delegate for a null value.");
+
+ System.Reflection.Emit.DynamicMethod dmGetter = new System.Reflection.Emit.DynamicMethod("getter", typeof(object), new Type[] { typeof(object) }, fieldInfo.DeclaringType.Module, true);
+ ILGenerator il = dmGetter.GetILGenerator();
+ if (fieldInfo.IsLiteral)
+ {
+ object value = fieldInfo.GetValue(null);
+ EmitConstant(il, value);
+ }
+ else if (fieldInfo.IsStatic)
+ {
+ il.Emit(OpCodes.Ldsfld, fieldInfo);
+ }
+ else
+ {
+ EmitTarget(il, fieldInfo.DeclaringType);
+ il.Emit(OpCodes.Ldfld, fieldInfo);
+ }
+
+ if (fieldInfo.FieldType.IsValueType)
+ {
+ il.Emit(OpCodes.Box, fieldInfo.FieldType);
+ }
+ il.Emit(OpCodes.Ret);
+ return (GetterDelegate)dmGetter.CreateDelegate(typeof(GetterDelegate));
+ }
+
+ /// <summary>
+ /// Create a new Set method delegate for the specified field using <see cref="System.Reflection.Emit.DynamicMethod"/>
+ /// </summary>
+ /// <param name="fieldInfo">the field to create the delegate for</param>
+ /// <returns>a delegate that can be used to read the field.</returns>
+ /// <remarks>
+ /// If the field's <see cref="FieldInfo.IsLiteral"/> returns true, the returned method
+ /// will throw an <see cref="InvalidOperationException"/> when called.
+ /// </remarks>
+ public static SetterDelegate CreateFieldSetter(FieldInfo fieldInfo)
+ {
+ AssertUtils.ArgumentNotNull(fieldInfo, "You cannot create a delegate for a null value.");
+
+ System.Reflection.Emit.DynamicMethod dmSetter = new System.Reflection.Emit.DynamicMethod("setter", null, new Type[] { typeof(object), typeof(object) }, fieldInfo.DeclaringType.Module, true);
+ ILGenerator il = dmSetter.GetILGenerator();
+
+ if (!fieldInfo.IsLiteral)
+ {
+ if (!fieldInfo.IsStatic)
+ {
+ EmitTarget(il, fieldInfo.DeclaringType);
+ }
+ il.Emit(OpCodes.Ldarg_1);
+ if (fieldInfo.FieldType.IsValueType)
+ {
+ il.Emit(OpCodes.Unbox_Any, fieldInfo.FieldType);
+ }
+ if (fieldInfo.IsStatic)
+ {
+ il.Emit(OpCodes.Stsfld, fieldInfo);
+ }
+ else
+ {
+ il.Emit(OpCodes.Stfld, fieldInfo);
+ }
+ il.Emit(OpCodes.Ret);
+ }
+ else
+ {
+ EmitThrowInvalidOperationException(il, string.Format("Cannot write to constant field '{0}.{1}'", fieldInfo.DeclaringType.FullName, fieldInfo.Name));
+ }
+ return (SetterDelegate)dmSetter.CreateDelegate(typeof(SetterDelegate));
+ }
+
+ /// <summary>
+ /// Create a new Get method delegate for the specified property using <see cref="System.Reflection.Emit.DynamicMethod"/>
+ /// </summary>
+ /// <param name="propertyInfo">the property to create the delegate for</param>
+ /// <returns>a delegate that can be used to read the property.</returns>
+ /// <remarks>
+ /// If the property's <see cref="PropertyInfo.CanRead"/> returns false, the returned method
+ /// will throw an <see cref="InvalidOperationException"/> when called.
+ /// </remarks>
+ public static GetterDelegate CreatePropertyGetter(PropertyInfo propertyInfo)
+ {
+ AssertUtils.ArgumentNotNull(propertyInfo, "You cannot create a delegate for a null value.");
+
+ NetDynamicMethod dm = new NetDynamicMethod(string.Empty, typeof(object), new Type[] { typeof(object) }, propertyInfo.DeclaringType.Module, true);
+ ILGenerator il = dm.GetILGenerator();
+
+ if (propertyInfo.CanRead)
+ {
+ MethodInfo method = propertyInfo.GetGetMethod(true);
+ if (!method.IsStatic)
+ {
+ EmitTarget(il, method.DeclaringType);
+ }
+ EmitCall(il, method);
+ if (propertyInfo.PropertyType.IsValueType)
+ {
+ il.Emit(OpCodes.Box, propertyInfo.PropertyType);
+ }
+ il.Emit(OpCodes.Ret);
+ }
+ else
+ {
+ EmitThrowInvalidOperationException(il, string.Format("Cannot read from write-only property '{0}.{1}'", propertyInfo.DeclaringType.FullName, propertyInfo.Name));
+ }
+ return (GetterDelegate)dm.CreateDelegate(typeof(GetterDelegate));
+ }
+
+ /// <summary>
+ /// Create a new Set method delegate for the specified property using <see cref="System.Reflection.Emit.DynamicMethod"/>
+ /// </summary>
+ /// <param name="propertyInfo">the property to create the delegate for</param>
+ /// <returns>a delegate that can be used to write the property.</returns>
+ /// <remarks>
+ /// If the property's <see cref="PropertyInfo.CanWrite"/> returns false, the returned method
+ /// will throw an <see cref="InvalidOperationException"/> when called.
+ /// </remarks>
+ public static SetterDelegate CreatePropertySetter(PropertyInfo propertyInfo)
+ {
+ AssertUtils.ArgumentNotNull(propertyInfo, "You cannot create a delegate for a null value.");
+
+ NetDynamicMethod dm = new NetDynamicMethod(string.Empty, null, new Type[] { typeof(object), typeof(object) }, propertyInfo.DeclaringType.Module, true);
+ ILGenerator il = dm.GetILGenerator();
+
+ if (propertyInfo.CanWrite)
+ {
+ MethodInfo method = propertyInfo.GetSetMethod(true);
+ if (!method.IsStatic)
+ {
+ EmitTarget(il, method.DeclaringType);
+ }
+
+ il.Emit(OpCodes.Ldarg_1);
+ if (propertyInfo.PropertyType.IsValueType)
+ {
+ il.Emit(OpCodes.Unbox_Any, propertyInfo.PropertyType);
+ }
+ EmitCall(il, method);
+ il.Emit(OpCodes.Ret);
+ }
+ else
+ {
+ EmitThrowInvalidOperationException(il, string.Format("Cannot write to read-only property '{0}.{1}'", propertyInfo.DeclaringType.FullName, propertyInfo.Name));
+ }
+
+ return (SetterDelegate)dm.CreateDelegate(typeof(SetterDelegate));
+ }
+
+ /// <summary>
+ /// Create a new method delegate for the specified method using <see cref="System.Reflection.Emit.DynamicMethod"/>
+ /// </summary>
+ /// <param name="method">the method to create the delegate for</param>
+ /// <returns>a delegate that can be used to invoke the method.</returns>
+ private static FunctionDelegate CreateFunctionDelegate(MethodInfo method)
+ {
+ NetDynamicMethod dm = new NetDynamicMethod(string.Empty, typeof(object), new Type[] { typeof(object), typeof(object[]) }, method.DeclaringType.Module, true);
+ ILGenerator il = dm.GetILGenerator();
+ ParameterInfo[] parameters = method.GetParameters();
+ for (int i = 0; i < parameters.Length; i++)
+ {
+ ParameterInfo p = parameters[i];
+ il.Emit(OpCodes.Ldarg_1);
+ il.Emit(OpCodes.Ldc_I4, i);
+ il.Emit(OpCodes.Ldelem_Ref);
+ if (p.ParameterType.IsValueType)
+ {
+ il.Emit(OpCodes.Unbox_Any, p.ParameterType);
+ }
+ }
+
+ if (!method.IsStatic)
+ {
+ EmitTarget(il, method.DeclaringType);
+ }
+ EmitCall(il, method);
+
+ if (method.ReturnType == typeof(void))
+ {
+ il.Emit(OpCodes.Ldnull);
+ }
+ il.Emit(OpCodes.Ret);
+ return (FunctionDelegate)dm.CreateDelegate(typeof(FunctionDelegate));
+ }
+
+ private static void EmitTarget(ILGenerator il, Type targetType)
+ {
+ il.Emit(OpCodes.Ldarg_0);
+ if (targetType.IsValueType)
+ {
+ LocalBuilder local = il.DeclareLocal(targetType);
+ il.Emit(OpCodes.Unbox_Any, targetType);
+ il.Emit(OpCodes.Stloc_0);
+ il.Emit(OpCodes.Ldloca_S, 0);
+ }
+ }
+
+ private static void EmitCall(ILGenerator il, MethodInfo method)
+ {
+ il.Emit((method.IsVirtual) ? OpCodes.Callvirt : OpCodes.Call, method);
+ }
+
+ private static void EmitConstant(ILGenerator il, object value)
+ {
+ if (value is String)
+ {
+ il.Emit(OpCodes.Ldstr, (string)value);
+ return;
+ }
+
+ if (value is bool)
+ {
+ if ((bool)value)
+ {
+ il.Emit(OpCodes.Ldc_I4_1);
+ }
+ else
+ {
+ il.Emit(OpCodes.Ldc_I4_0);
+ }
+ return;
+ }
+
+ if (value is Char)
+ {
+ il.Emit(OpCodes.Ldc_I4, (Char)value);
+ il.Emit(OpCodes.Conv_I2);
+ return;
+ }
+
+ if (value is byte)
+ {
+ il.Emit(OpCodes.Ldc_I4, (byte)value);
+ il.Emit(OpCodes.Conv_I1);
+ }
+ else if (value is Int16)
+ {
+ il.Emit(OpCodes.Ldc_I4, (Int16)value);
+ il.Emit(OpCodes.Conv_I2);
+ }
+ else if (value is Int32)
+ {
+ il.Emit(OpCodes.Ldc_I4, (Int32)value);
+ }
+ else if (value is Int64)
+ {
+ il.Emit(OpCodes.Ldc_I8, (Int64)value);
+ }
+ else if (value is UInt16)
+ {
+ il.Emit(OpCodes.Ldc_I4, (UInt16)value);
+ il.Emit(OpCodes.Conv_U2);
+ }
+ else if (value is UInt32)
+ {
+ il.Emit(OpCodes.Ldc_I4, (UInt32)value);
+ il.Emit(OpCodes.Conv_U4);
+ }
+ else if (value is UInt64)
+ {
+ il.Emit(OpCodes.Ldc_I8, (UInt64)value);
+ il.Emit(OpCodes.Conv_U8);
+ }
+ else if (value is Single)
+ {
+ il.Emit(OpCodes.Ldc_R4, (Single)value);
+ }
+ else if (value is Double)
+ {
+ il.Emit(OpCodes.Ldc_R8, (Double)value);
+ }
+ }
+
+ /// <summary>
+ /// Generates code that throws <see cref="InvalidOperationException"/>.
+ /// </summary>
+ /// <param name="il">IL generator to use.</param>
+ /// <param name="message">Error message to use.</param>
+ private static void EmitThrowInvalidOperationException(ILGenerator il, string message)
+ {
+ il.Emit(OpCodes.Ldstr, message);
+ il.Emit(OpCodes.Newobj, NewInvalidOperationException);
+ il.Emit(OpCodes.Throw);
+ }
+ #endif
}
}
\ No newline at end of file
Index: DynamicField.cs
===================================================================
RCS file: /cvsroot/springnet/Spring.Net/src/Spring/Spring.Core/Reflection/Dynamic/DynamicField.cs,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** DynamicField.cs 13 May 2008 14:22:46 -0000 1.2
--- DynamicField.cs 13 May 2008 23:23:03 -0000 1.3
***************
*** 77,117 ****
private readonly FieldInfo fieldInfo;
#if NET_2_0
! private readonly IDynamicField dynamicField;
! private static readonly Type[] s_ctorArgTypes = new Type[] { typeof(FieldInfo)};
! private static readonly Hashtable s_ctorCache = new Hashtable(100);
/// <summary>
! /// Returns a <see cref="IDynamicField"/> implementation
! /// by determining the fastest possible dynamic access strategy
/// </summary>
! /// <param name="field">the field to be wrapped</param>
! /// <returns>an <see cref="IDynamicField"/> instance for accessing the
! /// field represented by the given <see cref="FieldInfo"/></returns>
! public static IDynamicField CreateFrom(FieldInfo field)
{
! IDynamicField dynamicField;
! if (field.IsLiteral)
! {
! dynamicField = new LiteralField(field);
! }
! else if (field.IsStatic)
{
! ConstructorInfo ctor = typeof (StaticField<>).MakeGenericType(field.FieldType).GetConstructor(s_ctorArgTypes);
! dynamicField =
! (IDynamicField)ctor.Invoke(new object[] {field});
! // (IDynamicField)Activator.CreateInstance(typeof(StaticField<>).MakeGenericType(field.FieldType), field);
}
! else
{
! ConstructorInfo ctor = typeof (InstanceField<,>).MakeGenericType(field.FieldType, field.DeclaringType).GetConstructor(s_ctorArgTypes);
! dynamicField =
! (IDynamicField)ctor.Invoke(new object[] {field});
! // (IDynamicField) Activator.CreateInstance(typeof(InstanceField<,>).MakeGenericType(field.FieldType, field.DeclaringType), field);
}
!
! return dynamicField;
}
/// <summary>
/// Creates a new instance of the safe field wrapper.
--- 77,122 ----
private readonly FieldInfo fieldInfo;
#if NET_2_0
!
! #region Cache
!
! private static readonly IDictionary fieldCache = new Hashtable();
/// <summary>
! /// Holds cached Getter/Setter delegates for a Field
/// </summary>
! private class DynamicFieldCacheEntry
{
! public readonly GetterDelegate Getter;
! public readonly SetterDelegate Setter;
! public DynamicFieldCacheEntry(GetterDelegate getter, SetterDelegate setter)
{
! Getter = getter;
! Setter = setter;
}
! }
!
! /// <summary>
! /// Obtains cached fieldInfo or creates a new entry, if none is found.
! /// </summary>
! private static DynamicFieldCacheEntry GetOrCreateDynamicField(FieldInfo field)
! {
! DynamicFieldCacheEntry fieldInfo = (DynamicFieldCacheEntry)fieldCache[field];
! if (fieldInfo == null)
{
! fieldInfo = new DynamicFieldCacheEntry(DynamicReflectionManager.CreateFieldGetter(field), DynamicReflectionManager.CreateFieldSetter(field));
! lock (fieldCache)
! {
! fieldCache[field] = fieldInfo;
! }
}
! return fieldInfo;
}
+ #endregion
+
+ private readonly GetterDelegate getter;
+ private readonly SetterDelegate setter;
+
/// <summary>
/// Creates a new instance of the safe field wrapper.
***************
*** 120,125 ****
public SafeField(FieldInfo field)
{
fieldInfo = field;
! dynamicField = CreateFrom(field);
}
--- 125,134 ----
public SafeField(FieldInfo field)
{
+ AssertUtils.ArgumentNotNull(field, "You cannot create a dynamic field for a null value.");
+
fieldInfo = field;
! DynamicFieldCacheEntry fi = GetOrCreateDynamicField(field);
! getter = fi.Getter;
! setter = fi.Setter;
}
***************
*** 135,139 ****
public object GetValue(object target)
{
! return dynamicField.GetValue(target);
}
--- 144,148 ----
public object GetValue(object target)
{
! return getter(target);
}
***************
*** 149,282 ****
public void SetValue(object target, object value)
{
! dynamicField.SetValue(target, value);
! }
!
! #region Field Accessor Specializations
!
! /// <summary>
! /// wraps a constant field
! /// </summary>
! private class LiteralField : IDynamicField
! {
! private readonly object _value;
!
! public LiteralField(FieldInfo field)
! {
! _value = field.GetValue(null);
! }
!
! public object GetValue(object target)
! {
! return _value;
! }
!
! public void SetValue(object target, object value)
! {
! throw new NotSupportedException("value is readonly");
! }
! }
!
! /// <summary>
! /// wraps a static field
! /// </summary>
! private class StaticField<T> : IDynamicField
! {
! private delegate T Getter();
! private delegate void Setter(T value);
!
! private readonly FieldInfo field;
! private readonly Getter getter;
! private readonly Setter setter;
!
! public StaticField(FieldInfo field)
! {
! this.field = field;
! getter = CreateGetter(field);
! setter = CreateSetter(field);
! }
!
! public object GetValue(object target)
! {
! return getter();
! }
!
! public void SetValue(object target, object value)
! {
! setter((T)value);
! }
!
! private static Getter CreateGetter(FieldInfo fieldInfo)
! {
! ILGenerator ilGen;
! System.Reflection.Emit.DynamicMethod dmGetter = new System.Reflection.Emit.DynamicMethod("getter", fieldInfo.FieldType, null, fieldInfo.DeclaringType.Module, true);
! ilGen = dmGetter.GetILGenerator();
! ilGen.Emit(OpCodes.Ldsfld, fieldInfo);
! ilGen.Emit(OpCodes.Ret);
! return (Getter)dmGetter.CreateDelegate(typeof(Getter));
! }
!
! private static Setter CreateSetter(FieldInfo fieldInfo)
! {
! ILGenerator ilGen;
! System.Reflection.Emit.DynamicMethod dmSetter = new System.Reflection.Emit.DynamicMethod("setter", null, new Type[] { fieldInfo.FieldType }, fieldInfo.DeclaringType.Module, true);
! ilGen = dmSetter.GetILGenerator();
! ilGen.Emit(OpCodes.Ldarg_0);
! ilGen.Emit(OpCodes.Stsfld, fieldInfo);
! ilGen.Emit(OpCodes.Ret);
! return (Setter)dmSetter.CreateDelegate(typeof(Setter));
! }
! }
!
! private class InstanceField<T, O> : IDynamicField
! {
! private delegate T Getter(O target);
! private delegate void Setter(O target, T value);
!
! private readonly FieldInfo field;
! private readonly Getter getter;
! private readonly Setter setter;
!
! public InstanceField(FieldInfo field)
! {
! this.field = field;
! getter = GetGetter(field);
! setter = GetSetter(field);
! }
!
! public object GetValue(object target)
! {
! return getter((O)target);
! }
!
! public void SetValue(object target, object value)
! {
! setter((O)target, (T)value);
! }
!
! private static Getter GetGetter(FieldInfo fieldInfo)
! {
! ILGenerator ilGen;
! System.Reflection.Emit.DynamicMethod dmGetter = new System.Reflection.Emit.DynamicMethod("getter", fieldInfo.FieldType, new Type[] { fieldInfo.DeclaringType }, fieldInfo.DeclaringType.Module, true);
! ilGen = dmGetter.GetILGenerator();
! ilGen.Emit(OpCodes.Ldarg_0);
! ilGen.Emit(OpCodes.Ldfld, fieldInfo);
! ilGen.Emit(OpCodes.Ret);
! return (Getter)dmGetter.CreateDelegate(typeof(Getter));
! }
!
! private static Setter GetSetter(FieldInfo fieldInfo)
! {
! System.Reflection.Emit.DynamicMethod dmSetter = new System.Reflection.Emit.DynamicMethod("setter", null, new Type[] { fieldInfo.DeclaringType, fieldInfo.FieldType }, fieldInfo.DeclaringType.Module, true);
! ILGenerator ilGen = dmSetter.GetILGenerator();
! ilGen.Emit(OpCodes.Ldarg_0);
! ilGen.Emit(OpCodes.Ldarg_1);
! ilGen.Emit(OpCodes.Stfld, fieldInfo);
! ilGen.Emit(OpCodes.Ret);
! return (Setter)dmSetter.CreateDelegate(typeof(Setter));
! }
}
- #endregion
-
#else
/// <summary>
--- 158,164 ----
public void SetValue(object target, object value)
{
! setter(target, value);
}
#else
/// <summary>
Index: DynamicProperty.cs
===================================================================
RCS file: /cvsroot/springnet/Spring.Net/src/Spring/Spring.Core/Reflection/Dynamic/DynamicProperty.cs,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** DynamicProperty.cs 8 Aug 2007 04:05:37 -0000 1.1
--- DynamicProperty.cs 13 May 2008 23:23:03 -0000 1.2
***************
*** 22,25 ****
--- 22,26 ----
using System;
+ using System.Collections;
using System.Reflection;
using System.Reflection.Emit;
***************
*** 76,84 ****
public class SafeProperty : IDynamicProperty
{
! private static readonly ILog Log = LogManager.GetLogger(typeof (SafeProperty));
! private PropertyInfo propertyInfo;
! private IDynamicProperty dynamicProperty;
! private bool isOptimizedGet = false;
private bool isOptimizedSet = false;
--- 77,172 ----
public class SafeProperty : IDynamicProperty
{
! private static readonly ILog Log = LogManager.GetLogger(typeof(SafeProperty));
! private readonly PropertyInfo propertyInfo;
!
! #if NET_2_0
!
! #region Cache
!
! private static readonly IDictionary propertyCache = new Hashtable();
!
! /// <summary>
! /// Holds cached Getter/Setter delegates for a Property
! /// </summary>
! private class DynamicPropertyCacheEntry
! {
! public readonly GetterDelegate Getter;
! public readonly SetterDelegate Setter;
!
! public DynamicPropertyCacheEntry(GetterDelegate getter, SetterDelegate setter)
! {
! Getter = getter;
! Setter = setter;
! }
! }
!
! /// <summary>
! /// Obtains cached property info or creates a new entry, if none is found.
! /// </summary>
! private static DynamicPropertyCacheEntry GetOrCreateDynamicProperty(PropertyInfo property)
! {
! DynamicPropertyCacheEntry propertyInfo = (DynamicPropertyCacheEntry)propertyCache[property];
! if (propertyInfo == null)
! {
! propertyInfo = new DynamicPropertyCacheEntry(DynamicReflectionManager.CreatePropertyGetter(property), DynamicReflectionManager.CreatePropertySetter(property));
! lock (propertyCache)
! {
! propertyCache[property] = propertyInfo;
! }
! }
! return propertyInfo;
! }
!
! #endregion
!
! private readonly GetterDelegate getter;
! private readonly SetterDelegate setter;
!
! /// <summary>
! /// Creates a new instance of the safe property wrapper.
! /// </summary>
! /// <param name="propertyInfo">Property to wrap.</param>
! public SafeProperty(PropertyInfo propertyInfo)
! {
! AssertUtils.ArgumentNotNull(propertyInfo, "You cannot create a dynamic property for a null value.");
!
! this.propertyInfo = propertyInfo;
! DynamicPropertyCacheEntry pi = GetOrCreateDynamicProperty(propertyInfo);
! getter = pi.Getter;
! setter = pi.Setter;
! }
!
! /// <summary>
! /// Gets the value of the dynamic property for the specified target object.
! /// </summary>
! /// <param name="target">
! /// Target object to get property value from.
! /// </param>
! /// <returns>
! /// A property value.
! /// </returns>
! public object GetValue(object target)
! {
! return getter(target);
! }
!
! /// <summary>
! /// Gets the value of the dynamic property for the specified target object.
! /// </summary>
! /// <param name="target">
! /// Target object to set property value on.
! /// </param>
! /// <param name="value">
! /// A new property value.
! /// </param>
! public void SetValue(object target, object value)
! {
! setter(target, value);
! }
!
! #else
! private readonly IDynamicProperty dynamicProperty;
! private readonly bool isOptimizedGet = false;
private bool isOptimizedSet = false;
***************
*** 172,176 ****
}
}
!
/// <summary>
/// Internal PropertyInfo accessor.
--- 260,264 ----
}
}
! #endif
/// <summary>
/// Internal PropertyInfo accessor.
***************
*** 236,240 ****
Type dynamicPropertyType = tb.CreateType();
ConstructorInfo ctor = dynamicPropertyType.GetConstructor(Type.EmptyTypes);
! dynamicProperty = (IDynamicProperty) ctor.Invoke(ObjectUtils.EmptyObjects);
return dynamicProperty;
--- 324,328 ----
Type dynamicPropertyType = tb.CreateType();
ConstructorInfo ctor = dynamicPropertyType.GetConstructor(Type.EmptyTypes);
! dynamicProperty = (IDynamicProperty)ctor.Invoke(ObjectUtils.EmptyObjects);
return dynamicProperty;
***************
*** 244,248 ****
{
MethodBuilder getValueMethod =
! tb.DefineMethod("GetValue", METHOD_ATTRIBUTES, typeof (object), new Type[] {typeof (object)});
getValueMethod.DefineParameter(1, ParameterAttributes.None, "target");
--- 332,336 ----
{
MethodBuilder getValueMethod =
! tb.DefineMethod("GetValue", METHOD_ATTRIBUTES, typeof(object), new Type[] { typeof(object) });
getValueMethod.DefineParameter(1, ParameterAttributes.None, "target");
***************
*** 272,277 ****
{
MethodBuilder setValueMethod =
! tb.DefineMethod("SetValue", METHOD_ATTRIBUTES, typeof (void),
! new Type[] {typeof (object), typeof (object)});
setValueMethod.DefineParameter(1, ParameterAttributes.None, "target");
setValueMethod.DefineParameter(2, ParameterAttributes.None, "value");
--- 360,365 ----
{
MethodBuilder setValueMethod =
! tb.DefineMethod("SetValue", METHOD_ATTRIBUTES, typeof(void),
! new Type[] { typeof(object), typeof(object) });
setValueMethod.DefineParameter(1, ParameterAttributes.None, "target");
setValueMethod.DefineParameter(2, ParameterAttributes.None, "value");
|