public void GetArgumentValue() { ConstructorArgumentValues values = new ConstructorArgumentValues(); Assert.IsNull(values.GetArgumentValue(0, typeof(object)), "Mmm... managed to get a non null instance back from an empty instance."); values.AddGenericArgumentValue(DBNull.Value, typeof(DBNull).FullName); values.AddNamedArgumentValue("foo", DBNull.Value); values.AddIndexedArgumentValue(16, DBNull.Value, typeof(DBNull).FullName); Assert.IsNull(values.GetArgumentValue(100, typeof(string)), "Mmm... managed to get a non null instance back from an instance that should have now't with the specified Type."); ConstructorArgumentValues.ValueHolder value = values.GetArgumentValue(-3, typeof(DBNull)); Assert.IsNotNull(value, "Stored a value of a specified Type at a specified index, but got null when retrieving it using the wrong index but the correct Type."); Assert.AreSame(DBNull.Value, value.Value, "The retrieved value was not the exact same instance as was added."); value = values.GetArgumentValue("foo", typeof(DBNull)); Assert.IsNotNull(value, "Stored a value of a specified Type under a name, but got null when retrieving it using the wrong name but the correct Type."); Assert.AreSame(DBNull.Value, value.Value, "The retrieved value was not the exact same instance as was added."); }
public void GetArgumentValueIgnoresAlreadyUsedValues() { ISet used = new ListSet(); ConstructorArgumentValues values = new ConstructorArgumentValues(); values.AddGenericArgumentValue(1); values.AddNamedArgumentValue("2", 2); values.AddIndexedArgumentValue(3, 3); Type intType = typeof(int); ConstructorArgumentValues.ValueHolder one = values.GetArgumentValue(10, string.Empty, intType, used); Assert.AreEqual(1, one.Value); used.Add(one); ConstructorArgumentValues.ValueHolder two = values.GetArgumentValue(10, "2", intType, used); Assert.AreEqual(2, two.Value); used.Add(two); ConstructorArgumentValues.ValueHolder three = values.GetArgumentValue(3, string.Empty, intType, used); Assert.AreEqual(3, three.Value); used.Add(three); ConstructorArgumentValues.ValueHolder four = values.GetArgumentValue(10, string.Empty, intType, used); Assert.IsNull(four); }
public void GetArgumentValueIgnoresAlreadyUsedValues() { ISet used = new ListSet(); ConstructorArgumentValues values = new ConstructorArgumentValues(); values.AddGenericArgumentValue(1); values.AddNamedArgumentValue("2", 2); values.AddIndexedArgumentValue(3, 3); Type intType = typeof (int); ConstructorArgumentValues.ValueHolder one = values.GetArgumentValue(10, string.Empty, intType, used); Assert.AreEqual(1, one.Value); used.Add(one); ConstructorArgumentValues.ValueHolder two = values.GetArgumentValue(10, "2", intType, used); Assert.AreEqual(2, two.Value); used.Add(two); ConstructorArgumentValues.ValueHolder three = values.GetArgumentValue(3, string.Empty, intType, used); Assert.AreEqual(3, three.Value); used.Add(three); ConstructorArgumentValues.ValueHolder four = values.GetArgumentValue(10, string.Empty, intType, used); Assert.IsNull(four); }
/// <summary> /// Create an array of arguments to invoke a constructor or static factory method, /// given the resolved constructor arguments values. /// </summary> /// <remarks>When return value is null the out parameter UnsatisfiedDependencyExceptionData will contain /// information for use in throwing a UnsatisfiedDependencyException by the caller. This avoids using /// exceptions for flow control as in the original implementation.</remarks> private ArgumentsHolder CreateArgumentArray(string objectName, RootObjectDefinition rod, ConstructorArgumentValues resolvedValues, ObjectWrapper wrapper, Type[] paramTypes, MethodBase methodOrCtorInfo, bool autowiring, out UnsatisfiedDependencyExceptionData unsatisfiedDependencyExceptionData) { string methodType = (methodOrCtorInfo is ConstructorInfo) ? "constructor" : "factory method"; unsatisfiedDependencyExceptionData = null; ArgumentsHolder args = new ArgumentsHolder(paramTypes.Length); ISet usedValueHolders = new HybridSet(); IList autowiredObjectNames = new LinkedList(); bool resolveNecessary = false; ParameterInfo[] argTypes = methodOrCtorInfo.GetParameters(); for (int paramIndex = 0; paramIndex < paramTypes.Length; paramIndex++) { Type paramType = paramTypes[paramIndex]; string parameterName = argTypes[paramIndex].Name; // If we couldn't find a direct match and are not supposed to autowire, // let's try the next generic, untyped argument value as fallback: // it could match after type conversion (for example, String -> int). ConstructorArgumentValues.ValueHolder valueHolder = null; if (resolvedValues.GetNamedArgumentValue(parameterName) != null) { valueHolder = resolvedValues.GetArgumentValue(parameterName, paramType, usedValueHolders); } else { valueHolder = resolvedValues.GetArgumentValue(paramIndex, paramType, usedValueHolders); } if (valueHolder == null && !autowiring) { valueHolder = resolvedValues.GetGenericArgumentValue(null, usedValueHolders); } if (valueHolder != null) { // We found a potential match - let's give it a try. // Do not consider the same value definition multiple times! usedValueHolders.Add(valueHolder); args.rawArguments[paramIndex] = valueHolder.Value; try { object originalValue = valueHolder.Value; object convertedValue = TypeConversionUtils.ConvertValueIfNecessary(paramType, originalValue, null); args.arguments[paramIndex] = convertedValue; //? args.preparedArguments[paramIndex] = convertedValue; } catch (TypeMismatchException ex) { //To avoid using exceptions for flow control, this is not a cost in Java as stack trace is lazily created. string errorMessage = String.Format(CultureInfo.InvariantCulture, "Could not convert {0} argument value [{1}] to required type [{2}] : {3}", methodType, valueHolder.Value, paramType, ex.Message); unsatisfiedDependencyExceptionData = new UnsatisfiedDependencyExceptionData(paramIndex, paramType, errorMessage); return null; } } else { // No explicit match found: we're either supposed to autowire or // have to fail creating an argument array for the given constructor. if (!autowiring) { string errorMessage = String.Format(CultureInfo.InvariantCulture, "Ambiguous {0} argument types - " + "Did you specify the correct object references as {0} arguments?", methodType); unsatisfiedDependencyExceptionData = new UnsatisfiedDependencyExceptionData(paramIndex, paramType, errorMessage); return null; } try { MethodParameter param = MethodParameter.ForMethodOrConstructor(methodOrCtorInfo, paramIndex); object autowiredArgument = ResolveAutoWiredArgument(param, objectName, autowiredObjectNames); args.rawArguments[paramIndex] = autowiredArgument; args.arguments[paramIndex] = autowiredArgument; args.preparedArguments[paramIndex] = new AutowiredArgumentMarker(); resolveNecessary = true; } catch (ObjectsException ex) { unsatisfiedDependencyExceptionData = new UnsatisfiedDependencyExceptionData(paramIndex, paramType, ex.Message); return null; } } } foreach (string autowiredObjectName in autowiredObjectNames) { if (log.IsDebugEnabled) { log.Debug("Autowiring by type from object name '" + objectName + "' via " + methodType + " to object named '" + autowiredObjectName + "'"); } } return args; }
public void GetArgumentValue() { ConstructorArgumentValues values = new ConstructorArgumentValues(); Assert.IsNull(values.GetArgumentValue(0, typeof (object)), "Mmm... managed to get a non null instance back from an empty instance."); values.AddGenericArgumentValue(DBNull.Value, typeof (DBNull).FullName); values.AddNamedArgumentValue("foo", DBNull.Value); values.AddIndexedArgumentValue(16, DBNull.Value, typeof (DBNull).FullName); Assert.IsNull(values.GetArgumentValue(100, typeof (string)), "Mmm... managed to get a non null instance back from an instance that should have now't with the specified Type."); ConstructorArgumentValues.ValueHolder value = values.GetArgumentValue(-3, typeof (DBNull)); Assert.IsNotNull(value, "Stored a value of a specified Type at a specified index, but got null when retrieving it using the wrong index but the correct Type."); Assert.AreSame(DBNull.Value, value.Value, "The retrieved value was not the exact same instance as was added."); value = values.GetArgumentValue("foo", typeof (DBNull)); Assert.IsNotNull(value, "Stored a value of a specified Type under a name, but got null when retrieving it using the wrong name but the correct Type."); Assert.AreSame(DBNull.Value, value.Value, "The retrieved value was not the exact same instance as was added."); }