resolved SPRNET-969

This commit is contained in:
eeichinger
2008-10-21 21:56:20 +00:00
parent 7139e691e4
commit 62f21bb30b
24 changed files with 1980 additions and 897 deletions

View File

@@ -40,7 +40,7 @@ namespace Spring.Expressions
| BindingFlags.Instance | BindingFlags.Static
| BindingFlags.IgnoreCase;
private SafeIndexer indexer;
private SafeProperty indexer;
/// <summary>
/// Create a new instance
@@ -191,7 +191,7 @@ namespace Spring.Expressions
EvaluationContext evalContext = new EvaluationContext(context, variables);
InitializeIndexerProperty(context, evalContext);
return indexer.IndexerProperty;
return indexer.PropertyInfo;
}
}
@@ -260,7 +260,7 @@ namespace Spring.Expressions
private void SetGenericIndexer(object context, EvaluationContext evalContext,object newValue)
{
object[] indices = InitializeIndexerProperty( context, evalContext );
indexer.SetValue( context,indices,newValue );
indexer.SetValue( context, newValue, indices );
}
private object[] InitializeIndexerProperty(object context, EvaluationContext evalContext)
@@ -281,7 +281,7 @@ namespace Spring.Expressions
}
else
{
indexer = new SafeIndexer(indexerProperty);
indexer = new SafeProperty(indexerProperty);
}
}
}

View File

@@ -34,6 +34,8 @@ namespace Spring.Reflection.Dynamic
/// <author>Aleksandar Seovic</author>
public class BaseDynamicMember
{
//#if NET_2_0
//#else
/// <summary>
/// Method attributes constant.
/// </summary>
@@ -56,12 +58,12 @@ namespace Spring.Reflection.Dynamic
if (targetType.IsValueType)
{
LocalBuilder target = il.DeclareLocal(targetType);
#if NET_2_0
il.Emit(OpCodes.Unbox_Any, targetType);
#else
//#if NET_2_0
// il.Emit(OpCodes.Unbox_Any, targetType);
//#else
il.Emit(OpCodes.Unbox, targetType);
il.Emit(OpCodes.Ldobj, targetType);
#endif
//#endif
il.Emit(OpCodes.Stloc, target);
il.Emit(OpCodes.Ldloca, target);
}
@@ -82,12 +84,12 @@ namespace Spring.Reflection.Dynamic
il.Emit(OpCodes.Ldarg, argumentPosition);
if (argumentType.IsValueType)
{
#if NET_2_0
il.Emit(OpCodes.Unbox_Any, argumentType);
#else
//#if NET_2_0
// il.Emit(OpCodes.Unbox_Any, argumentType);
//#else
il.Emit(OpCodes.Unbox, argumentType);
il.Emit(OpCodes.Ldobj, argumentType);
#endif
//#endif
}
else
{
@@ -142,5 +144,6 @@ namespace Spring.Reflection.Dynamic
il.Emit(OpCodes.Newobj, invalidOperationException);
il.Emit(OpCodes.Throw);
}
//#endif
}
}

View File

@@ -21,6 +21,7 @@
#region Imports
using System;
using System.Collections;
using System.Reflection;
using System.Reflection.Emit;
using Spring.Util;
@@ -62,7 +63,59 @@ namespace Spring.Reflection.Dynamic
/// </remarks>
public class SafeConstructor : IDynamicConstructor
{
private ConstructorInfo constructor;
private ConstructorInfo constructorInfo;
#if NET_2_0
#region Generated Function Cache
private static readonly IDictionary constructorCache = new Hashtable();
/// <summary>
/// Obtains cached constructor info or creates a new entry, if none is found.
/// </summary>
private static ConstructorDelegate GetOrCreateDynamicConstructor(ConstructorInfo constructorInfo)
{
ConstructorDelegate method = (ConstructorDelegate)constructorCache[constructorInfo];
if (method == null)
{
method = DynamicReflectionManager.CreateConstructor(constructorInfo);
lock (constructorCache)
{
constructorCache[constructorInfo] = method;
}
}
return method;
}
#endregion
private ConstructorDelegate constructor;
/// <summary>
/// Creates a new instance of the safe constructor wrapper.
/// </summary>
/// <param name="constructorInfo">Constructor to wrap.</param>
public SafeConstructor(ConstructorInfo constructorInfo)
{
this.constructorInfo = constructorInfo;
this.constructor = GetOrCreateDynamicConstructor(constructorInfo);
}
/// <summary>
/// Invokes dynamic constructor.
/// </summary>
/// <param name="arguments">
/// Constructor arguments.
/// </param>
/// <returns>
/// A constructor value.
/// </returns>
public object Invoke(object[] arguments)
{
return constructor(arguments);
}
#else
private IDynamicConstructor dynamicConstructor;
private bool isOptimized = false;
@@ -72,7 +125,7 @@ namespace Spring.Reflection.Dynamic
/// <param name="constructor">Constructor to wrap.</param>
public SafeConstructor(ConstructorInfo constructor)
{
this.constructor = constructor;
this.constructorInfo = constructor;
if (constructor.IsPublic &&
ReflectionUtils.IsTypeVisible(constructor.DeclaringType, DynamicReflectionManager.ASSEMBLY_NAME))
{
@@ -80,7 +133,7 @@ namespace Spring.Reflection.Dynamic
this.isOptimized = true;
}
}
/// <summary>
/// Invokes dynamic constructor.
/// </summary>
@@ -103,18 +156,40 @@ namespace Spring.Reflection.Dynamic
catch (InvalidCastException)
{
isOptimized = false;
return constructor.Invoke(arguments);
return constructorInfo.Invoke(arguments);
}
}
else
{
return constructor.Invoke(arguments);
return constructorInfo.Invoke(arguments);
}
}
#endif
}
#endregion
#if NET_2_0
/// <summary>
/// Factory class for dynamic constructors.
/// </summary>
/// <author>Aleksandar Seovic</author>
public class DynamicConstructor : BaseDynamicMember
{
/// <summary>
/// Creates dynamic constructor instance for the specified <see cref="ConstructorInfo"/>.
/// </summary>
/// <param name="constructorInfo">Constructor info to create dynamic constructor for.</param>
/// <returns>Dynamic constructor for the specified <see cref="ConstructorInfo"/>.</returns>
public static IDynamicConstructor Create(ConstructorInfo constructorInfo)
{
AssertUtils.ArgumentNotNull(constructorInfo, "You cannot create a dynamic constructor for a null value.");
return new SafeConstructor(constructorInfo);
}
}
#else
/// <summary>
/// Factory class for dynamic constructors.
/// </summary>
@@ -162,37 +237,9 @@ namespace Spring.Reflection.Dynamic
ILGenerator il = invokeMethod.GetILGenerator();
Type[] argTypes = ReflectionUtils.GetParameterTypes(constructor);
for (int i = 0; i < argTypes.Length; i++)
{
SetupConstructorArgument(il, argTypes[i], i);
}
il.Emit(OpCodes.Newobj, constructor);
ProcessReturnValue(il, constructor.DeclaringType);
il.Emit(OpCodes.Ret);
}
private static void SetupConstructorArgument(ILGenerator il, Type argumentType, int argumentPosition)
{
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Ldc_I4, argumentPosition);
il.Emit(OpCodes.Ldelem_Ref);
if (argumentType.IsValueType)
{
#if NET_2_0
il.Emit(OpCodes.Unbox_Any, argumentType);
#else
il.Emit(OpCodes.Unbox, argumentType);
il.Emit(OpCodes.Ldobj, argumentType);
#endif
}
else
{
il.Emit(OpCodes.Castclass, argumentType);
}
}
DynamicReflectionManager.EmitInvokeConstructor(il, constructor, true);
}
#endregion
}
#endif
}

View File

@@ -85,10 +85,10 @@ namespace Spring.Reflection.Dynamic
/// </summary>
private class DynamicFieldCacheEntry
{
public readonly GetterDelegate Getter;
public readonly SetterDelegate Setter;
public readonly FieldGetterDelegate Getter;
public readonly FieldSetterDelegate Setter;
public DynamicFieldCacheEntry(GetterDelegate getter, SetterDelegate setter)
public DynamicFieldCacheEntry(FieldGetterDelegate getter, FieldSetterDelegate setter)
{
Getter = getter;
Setter = setter;
@@ -114,8 +114,8 @@ namespace Spring.Reflection.Dynamic
#endregion
private readonly GetterDelegate getter;
private readonly SetterDelegate setter;
private readonly FieldGetterDelegate getter;
private readonly FieldSetterDelegate setter;
/// <summary>
/// Creates a new instance of the safe field wrapper.

View File

@@ -1,5 +1,5 @@
#region License
#region License
/*
* Copyright <20> 2002-2007 the original author or authors.
*
@@ -14,128 +14,280 @@
* 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
#region Imports
using System;
using System.Collections;
using System.Reflection;
using System.Reflection.Emit;
using Spring.Reflection.Dynamic;
using Spring.Util;
#endregion
namespace Spring.Reflection.Dynamic
{
#region IDynamicIndexer interface
/// <summary>
/// Defines methods that dynamic indexer class has to implement.
/// </summary>
public interface IDynamicIndexer
{
/// <summary>
/// Gets the value of the dynamic indexer for the specified target object.
/// </summary>
/// <param name="target">
/// Target object to get the indexer value from.
/// </param>
/// <param name="index">
/// Indexer argument.
/// </param>
/// <returns>
/// A indexer value.
/// </returns>
object GetValue( object target, int index );
/// <summary>
/// Gets the value of the dynamic indexer for the specified target object.
/// </summary>
/// <param name="target">
/// Target object to get the indexer value from.
/// </param>
/// <param name="index">
/// Indexer argument.
/// </param>
/// <returns>
/// A indexer value.
/// </returns>
object GetValue( object target, object index );
/// <summary>
/// Gets the value of the dynamic indexer for the specified target object.
/// </summary>
/// <param name="target">
/// Target object to get the indexer value from.
/// </param>
/// <param name="index">
/// Indexer arguments.
/// </param>
/// <returns>
/// A indexer value.
/// </returns>
object GetValue( object target, object[] index );
/// <summary>
/// Gets the value of the dynamic indexer for the specified target object.
/// </summary>
/// <param name="target">
/// Target object to set the indexer value on.
/// </param>
/// <param name="index">
/// Indexer argument.
/// </param>
/// <param name="value">
/// A new indexer value.
/// </param>
void SetValue( object target, int index, object value );
/// <summary>
/// Gets the value of the dynamic indexer for the specified target object.
/// </summary>
/// <param name="target">
/// Target object to set the indexer value on.
/// </param>
/// <param name="index">
/// Indexer argument.
/// </param>
/// <param name="value">
/// A new indexer value.
/// </param>
void SetValue( object target, object index, object value );
/// <summary>
/// Gets the value of the dynamic indexer for the specified target object.
/// </summary>
/// <param name="target">
/// Target object to set the indexer value on.
/// </param>
/// <param name="index">
/// Indexer arguments.
/// </param>
/// <param name="value">
/// A new indexer value.
/// </param>
void SetValue( object target, object[] index, object value );
}
#endregion
#region Safe wrapper
#if NET_2_0
/// <summary>
/// Safe wrapper for the dynamic indexer.
/// </summary>
/// <remarks>
/// <see cref="SafeIndexer"/> will attempt to use dynamic
/// indexer if possible, but it will fall back to standard
/// reflection if necessary.
/// </remarks>
[Obsolete("Use SafeProperty instead", false)]
public class SafeIndexer : IDynamicIndexer
{
private PropertyInfo indexerProperty;
/// <summary>
/// Internal PropertyInfo accessor.
/// </summary>
internal PropertyInfo IndexerProperty
{
get { return indexerProperty; }
}
private SafeProperty property;
/// <summary>
/// Creates a new instance of the safe indexer wrapper.
/// </summary>
/// <param name="indexerInfo">Indexer to wrap.</param>
public SafeIndexer( PropertyInfo indexerInfo )
{
AssertUtils.ArgumentNotNull( indexerInfo, "You cannot create a dynamic indexer for a null value." );
this.indexerProperty = indexerInfo;
this.property = new SafeProperty( indexerInfo );
}
/// <summary>
/// Gets the value of the dynamic indexer for the specified target object.
/// </summary>
/// <param name="target">
/// Target object to get indexer value from.
/// </param>
/// <param name="index">
/// Indexer arguments.
/// </param>
/// <returns>
/// A indexer value.
/// </returns>
public object GetValue( object target, int index )
{
return property.GetValue( target, index );
}
/// <summary>
/// Gets the value of the dynamic indexer for the specified target object.
/// </summary>
/// <param name="target">
/// Target object to get the indexer value from.
/// </param>
/// <param name="index">
/// Indexer argument.
/// </param>
/// <returns>
/// A indexer value.
/// </returns>
public object GetValue( object target, object index )
{
return property.GetValue( target, index );
}
/// <summary>
/// Gets the value of the dynamic indexer for the specified target object.
/// </summary>
/// <param name="target">
/// Target object to get indexer value from.
/// </param>
/// <param name="index">
/// Indexer arguments.
/// </param>
/// <returns>
/// A indexer value.
/// </returns>
public object GetValue( object target, object[] index )
{
return property.GetValue( target, index );
}
/// <summary>
/// Sets the value of the dynamic indexer for the specified target object.
/// </summary>
/// <param name="target">
/// Target object to set indexer value on.
/// </param>
/// <param name="index">
/// Indexer arguments.
/// </param>
/// <param name="value">
/// A new indexer value.
/// </param>
public void SetValue( object target, int index, object value )
{
property.SetValue( target, value, index );
}
/// <summary>
/// Sets the value of the dynamic indexer for the specified target object.
/// </summary>
/// <param name="target">
/// Target object to set indexer value on.
/// </param>
/// <param name="index">
/// Indexer arguments.
/// </param>
/// <param name="value">
/// A new indexer value.
/// </param>
public void SetValue( object target, object index, object value )
{
property.SetValue( target, value, index );
}
/// <summary>
/// Sets the value of the dynamic indexer for the specified target object.
/// </summary>
/// <param name="target">
/// Target object to set indexer value on.
/// </param>
/// <param name="index">
/// Indexer arguments.
/// </param>
/// <param name="value">
/// A new indexer value.
/// </param>
public void SetValue( object target, object[] index, object value )
{
property.SetValue( target, value, index );
}
}
#else
#endregion
/// <summary>
/// Safe wrapper for the dynamic indexer.
/// </summary>
/// <remarks>
/// <see cref="SafeIndexer"/> will attempt to use dynamic
/// indexer if possible, but it will fall back to standard
/// reflection if necessary.
/// </remarks>
public class SafeIndexer : IDynamicIndexer
{
private PropertyInfo indexerProperty;
/// <summary>
/// Internal PropertyInfo accessor.
/// </summary>
internal PropertyInfo IndexerProperty
{
get { return indexerProperty; }
}
#region Imports
using System;
using System.Reflection;
using System.Reflection.Emit;
using Spring.Util;
#endregion
namespace Spring.Reflection.Dynamic
{
#region IDynamicIndexer interface
/// <summary>
/// Defines methods that dynamic indexer class has to implement.
/// </summary>
public interface IDynamicIndexer
{
/// <summary>
/// Gets the value of the dynamic indexer for the specified target object.
/// </summary>
/// <param name="target">
/// Target object to get the indexer value from.
/// </param>
/// <param name="index">
/// Indexer argument.
/// </param>
/// <returns>
/// A indexer value.
/// </returns>
object GetValue(object target, int index);
/// <summary>
/// Gets the value of the dynamic indexer for the specified target object.
/// </summary>
/// <param name="target">
/// Target object to get the indexer value from.
/// </param>
/// <param name="index">
/// Indexer argument.
/// </param>
/// <returns>
/// A indexer value.
/// </returns>
object GetValue(object target, object index);
/// <summary>
/// Gets the value of the dynamic indexer for the specified target object.
/// </summary>
/// <param name="target">
/// Target object to get the indexer value from.
/// </param>
/// <param name="index">
/// Indexer arguments.
/// </param>
/// <returns>
/// A indexer value.
/// </returns>
object GetValue(object target, object[] index);
/// <summary>
/// Gets the value of the dynamic indexer for the specified target object.
/// </summary>
/// <param name="target">
/// Target object to set the indexer value on.
/// </param>
/// <param name="index">
/// Indexer argument.
/// </param>
/// <param name="value">
/// A new indexer value.
/// </param>
void SetValue(object target, int index, object value);
/// <summary>
/// Gets the value of the dynamic indexer for the specified target object.
/// </summary>
/// <param name="target">
/// Target object to set the indexer value on.
/// </param>
/// <param name="index">
/// Indexer argument.
/// </param>
/// <param name="value">
/// A new indexer value.
/// </param>
void SetValue(object target, object index, object value);
/// <summary>
/// Gets the value of the dynamic indexer for the specified target object.
/// </summary>
/// <param name="target">
/// Target object to set the indexer value on.
/// </param>
/// <param name="index">
/// Indexer arguments.
/// </param>
/// <param name="value">
/// A new indexer value.
/// </param>
void SetValue(object target, object[] index, object value);
}
#endregion
#region Safe wrapper
/// <summary>
/// Safe wrapper for the dynamic indexer.
/// </summary>
/// <remarks>
/// <see cref="SafeIndexer"/> will attempt to use dynamic
/// indexer if possible, but it will fall back to standard
/// reflection if necessary.
/// </remarks>
public class SafeIndexer : IDynamicIndexer
{
private PropertyInfo indexerProperty;
private IDynamicIndexer dynamicIndexer;
private bool isOptimizedGet = false;
private bool isOptimizedSet = false;
@@ -334,18 +486,38 @@ namespace Spring.Reflection.Dynamic
indexerProperty.SetValue(target, value, index);
}
}
/// <summary>
/// Internal PropertyInfo accessor.
/// </summary>
internal PropertyInfo IndexerProperty
{
get { return indexerProperty; }
}
}
#endregion
}
#endif
#endregion
#if NET_2_0
/// <summary>
/// Factory class for dynamic indexers.
/// </summary>
/// <author>Aleksandar Seovic</author>
[Obsolete( "Use DynamicProperty instead", false )]
public sealed class DynamicIndexer : BaseDynamicMember
{
/// <summary>
/// Prevent instantiation
/// </summary>
private DynamicIndexer() { }
/// <summary>
/// Creates dynamic indexer instance for the specified <see cref="PropertyInfo"/>.
/// </summary>
/// <param name="indexer">Indexer info to create dynamic indexer for.</param>
/// <returns>Dynamic indexer for the specified <see cref="PropertyInfo"/>.</returns>
public static IDynamicIndexer Create( PropertyInfo indexer )
{
AssertUtils.ArgumentNotNull( indexer, "You cannot create a dynamic indexer for a null value." );
IDynamicIndexer dynamicIndexer = new SafeIndexer( indexer );
return dynamicIndexer;
}
}
#else
/// <summary>
/// Factory class for dynamic indexers.
/// </summary>
@@ -354,7 +526,7 @@ namespace Spring.Reflection.Dynamic
{
private static readonly CreateIndexerCallback s_createCallback = new CreateIndexerCallback(CreateInternal);
#region Create Method
#region Create Method
/// <summary>
/// Creates dynamic indexer instance for the specified <see cref="PropertyInfo"/>.
@@ -500,12 +672,8 @@ namespace Spring.Reflection.Dynamic
}
if (argumentType.IsValueType)
{
#if NET_2_0
il.Emit(OpCodes.Unbox_Any, argumentType);
#else
il.Emit(OpCodes.Unbox, argumentType);
il.Emit(OpCodes.Ldobj, argumentType);
#endif
}
else
{
@@ -513,6 +681,8 @@ namespace Spring.Reflection.Dynamic
}
}
#endregion
#endregion
}
}
#endif
} // namespace

View File

@@ -49,7 +49,7 @@ namespace Spring.Reflection.Dynamic
/// <returns>
/// A method return value.
/// </returns>
object Invoke(object target, object[] arguments);
object Invoke(object target, params object[] arguments);
}
#endregion
@@ -66,7 +66,71 @@ namespace Spring.Reflection.Dynamic
/// </remarks>
public class SafeMethod : IDynamicMethod
{
private MethodInfo method;
private readonly MethodInfo methodInfo;
/// <summary>
/// Gets the class, that declares this method
/// </summary>
public Type DeclaringType
{
get { return methodInfo.DeclaringType; }
}
#if NET_2_0
#region Generated Function Cache
private static readonly IDictionary methodCache = new Hashtable();
/// <summary>
/// Obtains cached property info or creates a new entry, if none is found.
/// </summary>
private static FunctionDelegate GetOrCreateDynamicMethod(MethodInfo methodInfo)
{
FunctionDelegate method = (FunctionDelegate)methodCache[methodInfo];
if (method == null)
{
method = DynamicReflectionManager.CreateMethod(methodInfo);
lock (methodCache)
{
methodCache[methodInfo] = method;
}
}
return method;
}
#endregion
private readonly FunctionDelegate method;
/// <summary>
/// Creates a new instance of the safe method wrapper.
/// </summary>
/// <param name="methodInfo">Method to wrap.</param>
public SafeMethod(MethodInfo methodInfo)
{
AssertUtils.ArgumentNotNull(methodInfo, "You cannot create a dynamic method for a null value.");
this.methodInfo = methodInfo;
this.method = GetOrCreateDynamicMethod(methodInfo);
}
/// <summary>
/// Invokes dynamic method.
/// </summary>
/// <param name="target">
/// Target object to invoke method on.
/// </param>
/// <param name="arguments">
/// Method arguments.
/// </param>
/// <returns>
/// A method return value.
/// </returns>
public object Invoke(object target, object[] arguments)
{
return this.method(target, arguments);
}
#else
private IDynamicMethod dynamicMethod;
private bool isOptimized = false;
@@ -76,7 +140,7 @@ namespace Spring.Reflection.Dynamic
/// <param name="method">Method to wrap.</param>
public SafeMethod(MethodInfo method)
{
this.method = method;
this.methodInfo = method;
if (method.IsPublic &&
ReflectionUtils.IsTypeVisible(method.DeclaringType, DynamicReflectionManager.ASSEMBLY_NAME))
{
@@ -85,14 +149,6 @@ namespace Spring.Reflection.Dynamic
}
}
/// <summary>
/// Gets the class, that declares this method
/// </summary>
public Type DeclaringType
{
get { return method.DeclaringType; }
}
/// <summary>
/// Invokes dynamic method.
/// </summary>
@@ -123,12 +179,12 @@ namespace Spring.Reflection.Dynamic
throw;
}
isOptimized = false;
return method.Invoke(target, arguments);
return methodInfo.Invoke(target, arguments);
}
}
else
{
return method.Invoke(target, arguments);
return methodInfo.Invoke(target, arguments);
}
}
@@ -136,10 +192,32 @@ namespace Spring.Reflection.Dynamic
{
return e.TargetSite.DeclaringType.FullName.IndexOf(DynamicReflectionManager.ASSEMBLY_NAME) >= 0;
}
#endif
}
#endregion
#if NET_2_0
/// <summary>
/// Factory class for dynamic methods.
/// </summary>
/// <author>Aleksandar Seovic</author>
public class DynamicMethod : BaseDynamicMember
{
/// <summary>
/// Creates dynamic method instance for the specified <see cref="MethodInfo"/>.
/// </summary>
/// <param name="method">Method info to create dynamic method for.</param>
/// <returns>Dynamic method for the specified <see cref="MethodInfo"/>.</returns>
public static IDynamicMethod Create(MethodInfo method)
{
AssertUtils.ArgumentNotNull(method, "You cannot create a dynamic method for a null value.");
IDynamicMethod dynamicMethod = new SafeMethod(method);
return dynamicMethod;
}
}
#else
/// <summary>
/// Factory class for dynamic methods.
/// </summary>
@@ -187,104 +265,11 @@ namespace Spring.Reflection.Dynamic
invokeMethod.DefineParameter(2, ParameterAttributes.None, "args");
ILGenerator il = invokeMethod.GetILGenerator();
bool isValueType = method.DeclaringType.IsValueType;
bool isStatic = method.IsStatic;
IDictionary outArgs = new Hashtable();
ParameterInfo[] args = method.GetParameters();
for (int i = 0; i < args.Length; i++)
{
if (IsOutputOrRefArgument(args[i]))
{
SetupOutputArgument(il, args[i], outArgs);
}
}
if (!isStatic)
{
SetupTargetInstance(il, method.DeclaringType);
}
for (int i = 0; i < args.Length; i++)
{
SetupMethodArgument(il, args[i], outArgs);
}
InvokeMethod(il, isStatic, isValueType, method);
for (int i = 0; i < args.Length; i++)
{
if (IsOutputOrRefArgument(args[i]))
{
ProcessOutputArgument(il, args[i], outArgs);
}
}
ProcessReturnValue(il, method.ReturnType);
il.Emit(OpCodes.Ret);
}
private static bool IsOutputOrRefArgument(ParameterInfo argInfo)
{
return argInfo.IsOut || argInfo.ParameterType.Name.EndsWith("&");
}
private static void SetupOutputArgument(ILGenerator il, ParameterInfo argInfo, IDictionary outArgs)
{
Type argType = argInfo.ParameterType.GetElementType();
LocalBuilder lb = il.DeclareLocal(argType);
if (!argInfo.IsOut)
{
PushArgumentValue(il, argType, argInfo.Position);
il.Emit(OpCodes.Stloc, lb);
}
outArgs[argInfo.Position] = lb;
}
private static void ProcessOutputArgument(ILGenerator il, ParameterInfo argInfo, IDictionary outArgs)
{
Type argType = argInfo.ParameterType.GetElementType();
il.Emit(OpCodes.Ldarg_2);
il.Emit(OpCodes.Ldc_I4, argInfo.Position);
il.Emit(OpCodes.Ldloc, (LocalBuilder)outArgs[argInfo.Position]);
if (argType.IsValueType)
{
il.Emit(OpCodes.Box, argType);
}
il.Emit(OpCodes.Stelem_Ref);
}
private static void SetupMethodArgument(ILGenerator il, ParameterInfo argInfo, IDictionary outArgs)
{
if (IsOutputOrRefArgument(argInfo))
{
il.Emit(OpCodes.Ldloca_S, (LocalBuilder)outArgs[argInfo.Position]);
}
else
{
PushArgumentValue(il, argInfo.ParameterType, argInfo.Position);
}
}
private static void PushArgumentValue(ILGenerator il, Type argumentType, int argumentPosition)
{
il.Emit(OpCodes.Ldarg_2);
il.Emit(OpCodes.Ldc_I4, argumentPosition);
il.Emit(OpCodes.Ldelem_Ref);
if (argumentType.IsValueType)
{
#if NET_2_0
il.Emit(OpCodes.Unbox_Any, argumentType);
#else
il.Emit(OpCodes.Unbox, argumentType);
il.Emit(OpCodes.Ldobj, argumentType);
#endif
}
else
{
il.Emit(OpCodes.Castclass, argumentType);
}
DynamicReflectionManager.EmitInvokeMethod(il, method, true);
}
#endregion
}
#endif
}

View File

@@ -60,6 +60,30 @@ namespace Spring.Reflection.Dynamic
/// A new property value.
/// </param>
void SetValue(object target, object value);
/// <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>
/// <param name="index">Optional index values for indexed properties. This value should be null reference for non-indexed properties.</param>
/// <returns>
/// A property value.
/// </returns>
object GetValue(object target, params object[] index);
/// <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>
/// <param name="index">Optional index values for indexed properties. This value should be null reference for non-indexed properties.</param>
void SetValue(object target, object value, params object[] index);
}
#endregion
@@ -91,10 +115,10 @@ namespace Spring.Reflection.Dynamic
/// </summary>
private class DynamicPropertyCacheEntry
{
public readonly GetterDelegate Getter;
public readonly SetterDelegate Setter;
public readonly PropertyGetterDelegate Getter;
public readonly PropertySetterDelegate Setter;
public DynamicPropertyCacheEntry(GetterDelegate getter, SetterDelegate setter)
public DynamicPropertyCacheEntry(PropertyGetterDelegate getter, PropertySetterDelegate setter)
{
Getter = getter;
Setter = setter;
@@ -120,8 +144,8 @@ namespace Spring.Reflection.Dynamic
#endregion
private readonly GetterDelegate getter;
private readonly SetterDelegate setter;
private readonly PropertyGetterDelegate getter;
private readonly PropertySetterDelegate setter;
/// <summary>
/// Creates a new instance of the safe property wrapper.
@@ -151,6 +175,21 @@ namespace Spring.Reflection.Dynamic
return getter(target);
}
/// <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>
/// <param name="index">Optional index values for indexed properties. This value should be null reference for non-indexed properties.</param>
/// <returns>
/// A property value.
/// </returns>
public object GetValue(object target, params object[] index)
{
return getter(target, index);
}
/// <summary>
/// Gets the value of the dynamic property for the specified target object.
/// </summary>
@@ -165,6 +204,21 @@ namespace Spring.Reflection.Dynamic
setter(target, value);
}
/// <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>
/// <param name="index">Optional index values for indexed properties. This value should be null reference for non-indexed properties.</param>
public void SetValue(object target, object value, params object[] index)
{
setter(target, value, index);
}
#else
private readonly IDynamicProperty dynamicProperty;
private readonly bool isOptimizedGet = false;
@@ -239,8 +293,9 @@ namespace Spring.Reflection.Dynamic
{
dynamicProperty.SetValue(target, value);
}
catch (InvalidCastException)
catch (InvalidCastException ex)
{
Log.Debug("Failed optimized set", ex);
isOptimizedSet = false;
propertyInfo.SetValue(target, value, null);
}
@@ -268,6 +323,64 @@ namespace Spring.Reflection.Dynamic
throw;
}
}
/// <summary>
/// Gets the value of the dynamic indexer for the specified target object.
/// </summary>
/// <param name="target">
/// Target object to get indexer value from.
/// </param>
/// <param name="index">
/// Indexer arguments.
/// </param>
/// <returns>
/// A indexer value.
/// </returns>
public object GetValue(object target, object[] index)
{
if (isOptimizedGet)
{
try
{
return dynamicProperty.GetValue(target, index);
}
catch (InvalidCastException)
{
isOptimizedSet = false;
}
}
return propertyInfo.GetValue(target, index);
}
/// <summary>
/// Sets the value of the dynamic indexer for the specified target object.
/// </summary>
/// <param name="target">
/// Target object to set indexer value on.
/// </param>
/// <param name="index">
/// Indexer arguments.
/// </param>
/// <param name="value">
/// A new indexer value.
/// </param>
public void SetValue(object target, object value, object[] index)
{
if (isOptimizedSet)
{
try
{
dynamicProperty.SetValue(target, value, index);
return;
}
catch (InvalidCastException ex)
{
Log.Debug("Failed optimized set", ex);
isOptimizedSet = false;
}
}
propertyInfo.SetValue(target, value, index);
}
#endif
/// <summary>
/// Internal PropertyInfo accessor.
@@ -364,7 +477,9 @@ namespace Spring.Reflection.Dynamic
tb.AddInterfaceImplementation(typeof(IDynamicProperty));
GenerateGetValue(tb, property);
GenerateGetIndexedValue(tb, property);
GenerateSetValue(tb, property);
GenerateSetIndexedValue(tb, property);
Type dynamicPropertyType = tb.CreateType();
ConstructorInfo ctor = dynamicPropertyType.GetConstructor(Type.EmptyTypes);
@@ -401,6 +516,41 @@ namespace Spring.Reflection.Dynamic
}
}
private static void GenerateGetIndexedValue(TypeBuilder tb, PropertyInfo indexer)
{
MethodBuilder getValueMethod =
tb.DefineMethod("GetValue", METHOD_ATTRIBUTES, typeof(object), new Type[] { typeof(object), typeof(object[]) });
getValueMethod.DefineParameter(1, ParameterAttributes.None, "target");
getValueMethod.DefineParameter(2, ParameterAttributes.None, "index");
ILGenerator il = getValueMethod.GetILGenerator();
if (indexer.CanRead)
{
MethodInfo getMethod = indexer.GetGetMethod();
bool isValueType = indexer.DeclaringType.IsValueType;
bool isStatic = getMethod.IsStatic;
if (!isStatic)
{
SetupTargetInstance(il, indexer.DeclaringType);
}
Type[] argTypes = ReflectionUtils.GetParameterTypes(getMethod);
for (int i = 0; i < argTypes.Length; i++)
{
SetupIndexerArgument(il, 2, argTypes[i], i, true);
}
InvokeMethod(il, isStatic, isValueType, getMethod);
ProcessReturnValue(il, indexer.PropertyType);
il.Emit(OpCodes.Ret);
}
else
{
ThrowInvalidOperationException(il, "Cannot get value of a non-readable indexer");
}
}
private static void GenerateSetValue(TypeBuilder tb, PropertyInfo property)
{
MethodBuilder setValueMethod =
@@ -440,6 +590,71 @@ namespace Spring.Reflection.Dynamic
}
}
private static void GenerateSetIndexedValue(TypeBuilder tb, PropertyInfo indexer)
{
MethodBuilder setValueMethod =
tb.DefineMethod("SetValue", METHOD_ATTRIBUTES, typeof(void),
new Type[] { typeof(object), typeof(object), typeof(object[]) });
setValueMethod.DefineParameter(1, ParameterAttributes.None, "target");
setValueMethod.DefineParameter(2, ParameterAttributes.None, "value");
setValueMethod.DefineParameter(3, ParameterAttributes.None, "index");
ILGenerator il = setValueMethod.GetILGenerator();
if (indexer.CanWrite)
{
bool isValueType = indexer.DeclaringType.IsValueType;
if (isValueType)
{
ThrowInvalidOperationException(il, "Cannot set indexer value on a value type due to boxing.");
}
else
{
MethodInfo setMethod = indexer.GetSetMethod();
bool isStatic = setMethod.IsStatic;
if (!isStatic)
{
SetupTargetInstance(il, indexer.DeclaringType);
}
Type[] argTypes = ReflectionUtils.GetParameterTypes(setMethod);
for (int i = 0; i < argTypes.Length - 1; i++)
{
SetupIndexerArgument(il, 3, argTypes[i], i, true);
}
SetupArgument(il, indexer.PropertyType, 2);
InvokeMethod(il, isStatic, isValueType, setMethod);
il.Emit(OpCodes.Ret);
}
}
else
{
ThrowInvalidOperationException(il, "Cannot set value of a read-only indexer");
}
}
private static OpCode[] LdArgOpCodes = { OpCodes.Ldarg_0, OpCodes.Ldarg_1, OpCodes.Ldarg_2, OpCodes.Ldarg_3 };
private static void SetupIndexerArgument(ILGenerator il, int indexArgumentPosition, Type argumentType, int argumentPosition, bool isObjectArray)
{
il.Emit(LdArgOpCodes[indexArgumentPosition]);
if (isObjectArray)
{
il.Emit(OpCodes.Ldc_I4, argumentPosition);
il.Emit(OpCodes.Ldelem_Ref);
}
if (argumentType.IsValueType)
{
il.Emit(OpCodes.Unbox, argumentType);
il.Emit(OpCodes.Ldobj, argumentType);
}
else
{
il.Emit(OpCodes.Castclass, argumentType);
}
}
#endregion
}

View File

@@ -260,16 +260,6 @@
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Util\ControlAccessor.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Util\ControlCollectionAccessor.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Util\HttpContextSwitch.cs"
SubType = "Code"
@@ -380,6 +370,16 @@
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Web\Support\ControlAccessor.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Web\Support\ControlCollectionAccessor.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Web\Support\ControlInterceptor.cs"
SubType = "Code"
@@ -460,6 +460,11 @@
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Web\Support\LocalResourceManager.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Web\Support\MappingHandlerFactory.cs"
SubType = "Code"
@@ -545,6 +550,11 @@
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Web\UI\IModelPersistenceMedium.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Web\UI\IValidationContainer.cs"
SubType = "Code"
@@ -560,6 +570,11 @@
SubType = "ASPXCodeBehind"
BuildAction = "Compile"
/>
<File
RelPath = "Web\UI\SessionModelPersistenceMedium.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Web\UI\UserControl.cs"
SubType = "ASPXCodeBehind"

View File

@@ -29,6 +29,8 @@ using Spring.Util;
#endregion
#if NET_2_0
namespace Spring.Web.Support
{
/// <summary>
@@ -88,4 +90,6 @@ namespace Spring.Web.Support
return null;
}
}
}
}
#endif

View File

@@ -21,10 +21,13 @@
#region Imports
using System;
using System.Collections.Generic;
using NUnit.Framework;
using Spring.Objects;
#if NET_2_0
using System.Collections.Generic;
#endif
#endregion
namespace Spring.Core.TypeResolution
@@ -39,10 +42,6 @@ namespace Spring.Core.TypeResolution
[Test]
public void CanTakeQualifiedType()
{
string tn = typeof(int[]).AssemblyQualifiedName;
tn = typeof(TestGenericObject<int,string>[]).AssemblyQualifiedName;
tn = typeof(List<int>).AssemblyQualifiedName;
Type testType = typeof(TestObject);
TypeAssemblyHolder tah = new TypeAssemblyHolder(testType.AssemblyQualifiedName);
Assert.IsTrue(tah.IsAssemblyQualified);

View File

@@ -1,6 +1,9 @@
using System;
using System.CodeDom.Compiler;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Text;
using NUnit.Framework;
using Spring.Context.Support;
@@ -74,6 +77,44 @@ namespace Spring.Reflection.Dynamic
Assert.AreEqual(mostImportantDayInTheWorldEver.Year, year.GetValue(mostImportantDayInTheWorldEver));
}
[Test]
public void AccessInheritedPropertyFromBaseClass()
{
IDynamicProperty p = Create(typeof(ClassWithNonReadableProperty).GetProperty("MyBaseProperty"));
BaseClass baseObject = new BaseClass();
baseObject.MyBaseProperty = "testtext";
Assert.AreEqual("testtext", p.GetValue(baseObject));
}
[Test]
public void AccessInheritedPropertyFromDerivedClass()
{
IDynamicProperty p = Create(typeof(BaseClass).GetProperty("MyBaseProperty"));
ClassWithNonReadableProperty derivedObject = new ClassWithNonReadableProperty();
derivedObject.MyBaseProperty = "testtext";
Assert.AreEqual("testtext", p.GetValue(derivedObject));
}
[Test]
public void AccessOverriddenProperty()
{
IDynamicProperty pVirt = Create(typeof(BaseClass).GetProperty("MyVirtualBaseProperty"));
IDynamicProperty pOverridden = Create(typeof(ClassWithNonReadableProperty).GetProperty("MyVirtualBaseProperty"));
Assert.AreEqual("MyVirtualBasePropertyText", pVirt.GetValue(new BaseClass()));
try
{
Assert.AreEqual("MyVirtualBasePropertyText", pOverridden.GetValue(new BaseClass()));
Assert.Fail();
}
catch (InvalidCastException)
{
}
Assert.AreEqual("MyOverridenDerivedPropertyText", pVirt.GetValue(new ClassWithNonReadableProperty()));
Assert.AreEqual("MyOverridenDerivedPropertyText", pOverridden.GetValue(new ClassWithNonReadableProperty()));
}
[Test]
public void TestStaticProperties()
{
@@ -178,7 +219,7 @@ namespace Spring.Reflection.Dynamic
#region IL generation helper classes (they help if you look at them in Reflector ;-)
public class ValueTypeProperty : IDynamicProperty
public class ValueTypeProperty //: IDynamicProperty
{
public object GetValue(object target)
{
@@ -191,7 +232,7 @@ namespace Spring.Reflection.Dynamic
}
}
public class ValueTypeTarget : IDynamicProperty
public class ValueTypeTarget //: IDynamicProperty
{
public object GetValue(object target)
{
@@ -205,7 +246,7 @@ namespace Spring.Reflection.Dynamic
}
}
public class StaticProperty : IDynamicProperty
public class StaticProperty //: IDynamicProperty
{
public object GetValue(object target)
{
@@ -256,7 +297,23 @@ namespace Spring.Reflection.Dynamic
}
}
public class ClassWithNonReadableProperty
public class BaseClass
{
private string myBaseProperty;
public string MyBaseProperty
{
set { myBaseProperty = value; }
get { return myBaseProperty; }
}
public virtual string MyVirtualBaseProperty
{
get { return "MyVirtualBasePropertyText"; }
}
}
public class ClassWithNonReadableProperty : BaseClass
{
private string myProperty;
@@ -264,6 +321,11 @@ namespace Spring.Reflection.Dynamic
{
set { myProperty = value; }
}
public override string MyVirtualBaseProperty
{
get { return "MyOverridenDerivedPropertyText"; }
}
}
#if NET_2_0

View File

@@ -108,6 +108,38 @@ namespace Spring.Reflection.Dynamic
Assert.IsFalse((bool) isNullOrEmpty.Invoke(null, new object[] { "Ana Maria" }));
}
[Test]
public void TestArgumentTypeCasts()
{
IDynamicMethod sqrt = DynamicMethod.Create(typeof(Math).GetMethod("Sqrt"));
object result = sqrt.Invoke(null, new object[] { 4 } );
Assert.AreEqual( Math.Sqrt(4), result );
try
{
sqrt.Invoke(null, new object[] { null } );
Assert.Fail();
}
catch (InvalidCastException)
{
}
try
{
sqrt.Invoke(null, new object[] { "4" } );
Assert.Fail();
}
catch (InvalidCastException)
{}
}
private void CodeForReflection()
{
object val = 4;
Type argType = typeof(double);
Math.Sqrt( (double)Convert.ChangeType(val, argType) );
}
[Test]
public void TestRefOutMethods()
{

View File

@@ -21,8 +21,11 @@
#region Imports
using System;
using System.CodeDom.Compiler;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Text;
using NUnit.Framework;
using Spring.Context.Support;
@@ -30,52 +33,52 @@ using Spring.Context.Support;
namespace Spring.Reflection.Dynamic
{
/// <summary>
/// <summary>
/// Unit tests for the DynamicProperty class.
/// </summary>
/// <author>Aleksandar Seovic</author>
[TestFixture]
[TestFixture]
public class DynamicPropertyTests : BasePropertyTests
{
protected override IDynamicProperty Create(PropertyInfo property)
protected override IDynamicProperty Create( PropertyInfo property )
{
return DynamicProperty.Create(property);
return DynamicProperty.Create( property );
}
[Test]
[ExpectedException(typeof(InvalidOperationException))]
[ExpectedException( typeof( InvalidOperationException ) )]
public void TestNonReadableProperties()
{
IDynamicProperty nonReadableProperty =
Create(typeof(ClassWithNonReadableProperty).GetProperty("MyProperty"));
nonReadableProperty.GetValue(null);
IDynamicProperty nonReadableProperty =
Create( typeof( ClassWithNonReadableProperty ).GetProperty( "MyProperty" ) );
nonReadableProperty.GetValue( null );
}
[Test]
[ExpectedException(typeof(InvalidOperationException))]
[ExpectedException( typeof( InvalidOperationException ) )]
public void TestNonWritableInstanceProperty()
{
IDynamicProperty nonWritableProperty =
Create(typeof(Inventor).GetProperty("PlaceOfBirth"));
nonWritableProperty.SetValue(null, null);
Create( typeof( Inventor ).GetProperty( "PlaceOfBirth" ) );
nonWritableProperty.SetValue( null, null );
}
[Test]
[ExpectedException(typeof(InvalidOperationException))]
[ExpectedException( typeof( InvalidOperationException ) )]
public void TestAttemptingToSetPropertyOfValueTypeInstance()
{
MyStruct myYearHolder = new MyStruct();
IDynamicProperty year = Create(typeof(MyStruct).GetProperty("Year"));
year.SetValue(myYearHolder, 2004);
IDynamicProperty year = Create( typeof( MyStruct ).GetProperty( "Year" ) );
year.SetValue( myYearHolder, 2004 );
}
[Test]
[ExpectedException(typeof(InvalidOperationException))]
[ExpectedException( typeof( InvalidOperationException ) )]
public void TestNonWritableStaticProperty()
{
IDynamicProperty nonWritableProperty =
Create(typeof(DateTime).GetProperty("Today"));
nonWritableProperty.SetValue(null, null);
}
Create( typeof( DateTime ).GetProperty( "Today" ) );
nonWritableProperty.SetValue( null, null );
}
}
}

View File

@@ -21,7 +21,11 @@
#region Imports
using System;
using System.CodeDom.Compiler;
using System.IO;
using System.Reflection;
using System.Text;
using Microsoft.VisualBasic;
using NUnit.Framework;
#endregion
@@ -41,6 +45,53 @@ namespace Spring.Reflection.Dynamic
return new SafeProperty(property);
}
[Test]
public void CanGetSetSimpleProperty()
{
object o = GetVisualBasicTestObject();
IDynamicProperty simpleProperty = Create(o.GetType().GetProperty("SimpleProperty"));
simpleProperty.SetValue(o, "CanGetSimpleText", "args");
Assert.AreEqual("CanGetSimpleText", ThisLastPropertyValue.GetValue(o));
Assert.AreEqual("CanGetSimpleText", simpleProperty.GetValue(o));
}
[Test]
public void CanGetSetSimpleIndexer()
{
object o = GetVisualBasicTestObject();
IDynamicProperty simpleProperty = Create(o.GetType().GetProperty("SimpleIndexer"));
// write
simpleProperty.SetValue(o, "CanGetSetSimpleIndexer", 2);
Assert.AreEqual("CanGetSetSimpleIndexer", ThisLastPropertyValue.GetValue(o));
Assert.AreEqual(2, ThisArg1.GetValue(o));
// read
object value = simpleProperty.GetValue(o, 3);
Assert.AreEqual("CanGetSetSimpleIndexer", value);
Assert.AreEqual(3, ThisArg1.GetValue(o));
}
[Test]
public void CanGetSetComplexIndexer()
{
object o = GetVisualBasicTestObject();
IDynamicProperty property = Create(o.GetType().GetProperty("ComplexIndexer"));
// write
property.SetValue(o, "CanGetSetComplexIndexer", 2, "Arg2");
Assert.AreEqual("CanGetSetComplexIndexer", ThisLastPropertyValue.GetValue(o));
Assert.AreEqual(2.0, (double)ThisArg1.GetValue(o));
Assert.AreEqual("Arg2", ThisArg2.GetValue(o));
// read
object value = property.GetValue(o, 3, "Arg3");
Assert.AreEqual("CanGetSetComplexIndexer", value);
Assert.AreEqual(3.0, (double)ThisArg1.GetValue(o));
Assert.AreEqual("Arg3", ThisArg2.GetValue(o));
}
#if NET_2_0
[Test]
public void TestForRestrictiveSetterWithSafeWrapper()
@@ -76,6 +127,60 @@ namespace Spring.Reflection.Dynamic
Assert.AreEqual(123, first.GetValue(something));
}
#endif
#region VB TestClass Code
private static Type s__visualBasicTestObjectType;
private static IDynamicField ThisLastPropertyValue;
private static IDynamicField ThisArg1;
private static IDynamicField ThisArg2;
private static IDynamicField ThisOptionalArg;
private static IDynamicField ThisParamsArg;
protected static object GetVisualBasicTestObject()
{
if (s__visualBasicTestObjectType == null)
{
// compile vb test class
string vbSourceCode = new StreamReader( Assembly.GetExecutingAssembly().GetManifestResourceStream( typeof( BasePropertyTests ), "SafePropertyTests_TestObject.vb" ) ).ReadToEnd();
CompilerParameters args = new CompilerParameters();
args.OutputAssembly = "VbTestObject.dll";
args.GenerateInMemory = true;
args.GenerateExecutable = false;
args.IncludeDebugInformation = true;
args.Evidence = Assembly.GetExecutingAssembly().Evidence;
#if NET_2_0
CodeDomProvider provider = CodeDomProvider.CreateProvider( "VisualBasic" );
CompilerResults results = provider.CompileAssemblyFromSource( args, vbSourceCode );
#else
CodeDomProvider provider = new VBCodeProvider();
ICodeCompiler compiler = provider.CreateCompiler();
CompilerResults results = compiler.CompileAssemblyFromSource( args, vbSourceCode );
#endif
if (results.Errors.HasErrors)
{
StringBuilder sb = new StringBuilder();
foreach (CompilerError error in results.Errors)
{
sb.Append( error.ToString() ).Append( "\n\r" );
}
throw new TypeLoadException( "failed compiling test class: " + sb );
}
s__visualBasicTestObjectType = results.CompiledAssembly.GetType( "VbTestObject" );
ThisLastPropertyValue = DynamicField.Create( s__visualBasicTestObjectType.GetField("ThisLastPropertyValue") );
ThisArg1 = DynamicField.Create( s__visualBasicTestObjectType.GetField("ThisArg1") );
ThisArg2 = DynamicField.Create( s__visualBasicTestObjectType.GetField("ThisArg2") );
ThisOptionalArg = DynamicField.Create( s__visualBasicTestObjectType.GetField("ThisOptionalArg") );
ThisParamsArg = DynamicField.Create( s__visualBasicTestObjectType.GetField("ThisParamsArgs") );
}
object s__visualBasicTestObject = Activator.CreateInstance(s__visualBasicTestObjectType);
return s__visualBasicTestObject;
}
#endregion
}
#region Test Classes

View File

@@ -0,0 +1,68 @@
Public Class VbTestObject
Public ThisArg1 As Object
Public ThisArg2 As Object
Public ThisOptionalArg As Object
Public ThisParamsArgs As Object()
Public ThisLastPropertyValue As Object
Property SimpleProperty() As String
Get
Return ThisLastPropertyValue
End Get
Set(ByVal value As String)
ThisLastPropertyValue = value
End Set
End Property
Property SimpleIndexer(ByVal arg1 As Integer) As String
Get
ThisArg1 = arg1
Return ThisLastPropertyValue
End Get
Set(ByVal value As String)
ThisArg1 = arg1
ThisLastPropertyValue = value
End Set
End Property
Default Property ComplexIndexer(ByVal arg1 As Double, ByVal arg2 As Object) As String
Get
ThisArg1 = arg1
ThisArg2 = arg2
Return ThisLastPropertyValue
End Get
Set(ByVal value As String)
ThisArg1 = arg1
ThisArg2 = arg2
ThisLastPropertyValue = value
End Set
End Property
Property PropertyWithParamsArgs(ByVal arg1 As String, ByVal ParamArray paramsArgs As Object()) As String
Get
ThisArg1 = arg1
ThisParamsArgs = paramsArgs
Return ThisLastPropertyValue
End Get
Set(ByVal value As String)
ThisArg1 = arg1
ThisParamsArgs = paramsArgs
ThisLastPropertyValue = value
End Set
End Property
Property PropertyWithOptionalArg(ByVal arg1 As String, Optional ByVal optionalArg As Object = "Empty") As String
Get
ThisArg1 = arg1
ThisOptionalArg = optionalArg
Return ThisLastPropertyValue
End Get
Set(ByVal value As String)
ThisArg1 = arg1
ThisOptionalArg = optionalArg
ThisLastPropertyValue = value
End Set
End Property
End Class

View File

@@ -1744,6 +1744,10 @@
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Reflection\Dynamic\SafePropertyTests_TestObject.vb"
BuildAction = "EmbeddedResource"
/>
<File
RelPath = "Resources\Images.resx"
BuildAction = "EmbeddedResource"

View File

@@ -640,6 +640,7 @@
<SubType>Code</SubType>
</Compile>
<Compile Include="Reflection\Dynamic\BasePropertyTests.cs" />
<EmbeddedResource Include="Reflection\Dynamic\SafePropertyTests_TestObject.vb" />
<Compile Include="Reflection\Dynamic\DynamicConstructorTests.cs" />
<Compile Include="Reflection\Dynamic\DynamicFieldTests.cs" />
<Compile Include="Reflection\Dynamic\DynamicIndexerTests.cs" />

View File

@@ -30,6 +30,7 @@
<include name="**/*.resx" />
<include name="**/*.xsd" />
<include name="**/*.txt" />
<include name="**/*.vb" />
<include name="**/*.properties" />
<include name="**/SimpleAppContext.xml" />
<include name="**/Factory/Attributes/*.xml" />

View File

@@ -151,6 +151,11 @@
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Data\AdoTemplatePerformanceTests.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Data\AdoTemplateTests.cs"
SubType = "Code"
@@ -272,6 +277,11 @@
RelPath = "Data\nativeAdoTests.xml"
BuildAction = "EmbeddedResource"
/>
<File
RelPath = "Data\NestedTxScopeTests.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Data\OracleAdoTemplateTests.cs"
SubType = "Code"
@@ -296,6 +306,11 @@
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Data\SQLiteTests.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Data\StoredProcedureTests.cs"
SubType = "Code"
@@ -334,11 +349,44 @@
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Data\TestTxIsolationLevel.xml"
BuildAction = "EmbeddedResource"
/>
<File
RelPath = "Data\TestTxIsolationLevelTests.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Data\TransactionTemplateTests.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Data\Generic\GenericAdoTemplateTests.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Data\Generic\GenericAdoTemplateTests.xml"
BuildAction = "Content"
/>
<File
RelPath = "Data\Generic\ITestObjectDao.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Data\Generic\TestObjectDao.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Data\Generic\TestObjectRowMapper.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Data\Northwind\AdoTemplateShipperDao.cs"
SubType = "Code"
@@ -359,6 +407,26 @@
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Data\Objects\Generic\MappingVacationQuery.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Data\Objects\Generic\StoredProcedureTests.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Data\Objects\Generic\Vacation.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Data\Objects\Generic\VacationRowMapper.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Data\Support\SimpleExceptionTranslationTests.cs"
SubType = "Code"

View File

@@ -1,7 +1,7 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<PropertyGroup>
<ProjectType>Local</ProjectType>
<ProductVersion>9.0.21022</ProductVersion>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{91766D21-C568-459F-9BEA-759B011F23CF}</ProjectGuid>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -127,6 +127,7 @@
<Compile Include="Data\AutoDeclarativeTxTests.cs" />
<Compile Include="Data\CallCreateTestObject.cs" />
<Compile Include="Data\ConsoleLoggingAroundAdvice.cs" />
<Compile Include="Data\OracleAdoTemplateTests.cs" />
<Compile Include="Data\TestTxIsolationLevelTests.cs" />
<Compile Include="Data\Generic\GenericAdoTemplateTests.cs" />
<Compile Include="Data\Generic\ITestObjectDao.cs" />
@@ -185,6 +186,12 @@
<ItemGroup>
<EmbeddedResource Include="Data\TestTxIsolationLevel.xml" />
</ItemGroup>
<ItemGroup>
<Content Include="Data\CreateTestObject.sql" />
<Content Include="Data\CreditsDebitsSchema.sql" />
<Content Include="Data\DTC1.1AppContext.xml" />
<Content Include="Data\testobjects-sqlserver.sql" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PreBuildEvent>

View File

@@ -244,6 +244,11 @@
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "TestSupport\DictionaryModelPersistenceMedium.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "TestSupport\NUnitAdapter.cs"
SubType = "Code"
@@ -259,6 +264,11 @@
SubType = "ASPXCodeBehind"
BuildAction = "Compile"
/>
<File
RelPath = "TestSupport\TestUserControl.cs"
SubType = "ASPXCodeBehind"
BuildAction = "Compile"
/>
<File
RelPath = "TestSupport\TestWebContext.cs"
SubType = "Code"
@@ -289,15 +299,6 @@
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Util\ControlInterceptionTests.cs"
SubType = "ASPXCodeBehind"
BuildAction = "Compile"
/>
<File
RelPath = "Util\ControlInterceptionTests.objects.xml"
BuildAction = "EmbeddedResource"
/>
<File
RelPath = "Util\WebDIPerformanceTests.cs"
SubType = "Code"
@@ -318,6 +319,20 @@
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Web\Support\ControlInterceptionTests.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Web\Support\ControlInterceptionTests.objects.xml"
BuildAction = "EmbeddedResource"
/>
<File
RelPath = "Web\Support\LocalResourceManagerTests.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Web\Support\MimeMediaTypeTests.cs"
SubType = "Code"
@@ -343,6 +358,11 @@
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Web\UI\SessionModelPersistenceMediumTests.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Web\UI\UserControlTests.cs"
SubType = "Code"

View File

@@ -30,7 +30,7 @@ using Spring.Web.Support;
#endregion
namespace Spring.Util
namespace Spring.Web.Support
{
/// <summary>
/// Unit tests for the ControlInterceptor class.
@@ -40,7 +40,7 @@ namespace Spring.Util
public class ControlInterceptionTests
{
private const string RES_OBJECTS =
"assembly://Spring.Web.Tests/Spring.Util/ControlInterceptionTests.objects.xml";
"assembly://Spring.Web.Tests/Spring.Web.Support/ControlInterceptionTests.objects.xml";
static ControlInterceptionTests()
{

View File

@@ -2,7 +2,7 @@
<objects xmlns="http://www.springframework.net">
<object id="Spring.Util.MockControl" abstract="true">
<object id="Spring.Web.Support.MockControl" abstract="true">
<property name="GotIt" value="true" />
</object>