Update of /cvsroot/springnet/Spring.Net/src/Spring/Spring.Core/Objects/Factory/Support
In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv8700
Modified Files:
AbstractAutowireCapableObjectFactory.cs
Log Message:
SPRNET-900 - AbstractAutoWireCapableObjectFactory throws exceptions in primary control path, modify to avoid use of exceptions for flow control
Index: AbstractAutowireCapableObjectFactory.cs
===================================================================
RCS file: /cvsroot/springnet/Spring.Net/src/Spring/Spring.Core/Objects/Factory/Support/AbstractAutowireCapableObjectFactory.cs,v
retrieving revision 1.87
retrieving revision 1.88
diff -C2 -d -r1.87 -r1.88
*** AbstractAutowireCapableObjectFactory.cs 5 Apr 2008 13:35:35 -0000 1.87
--- AbstractAutowireCapableObjectFactory.cs 5 May 2008 21:30:47 -0000 1.88
***************
*** 993,999 ****
--- 993,1001 ----
MethodInfo[] factoryMethods = FindMethods(genericArgsInfo.GenericMethodName, expectedArgCount, isStatic, factoryClass);
+ UnsatisfiedDependencyExceptionData unsatisfiedDependencyExceptionData = null;
// try all matching methods to see if they match the constructor arguments...
for (int i = 0; i < factoryMethods.Length; i++)
{
+ unsatisfiedDependencyExceptionData = null;
MethodInfo factoryMethod = factoryMethods[i];
***************
*** 1017,1034 ****
{
#endif
! try
{
// try to create the required arguments...
! if (arguments == null || arguments.Length == 0)
{
! arguments = CreateArgumentArray(name, definition, resolvedValues, factoryMethod);
}
}
- catch
- {
- // if we failed to match this method, swallow the exception and keep
- // trying new overloaded factory methods...
- continue;
- }
// if we get here, we found a factory method...
--- 1019,1033 ----
{
#endif
! if (arguments == null || arguments.Length == 0)
{
// try to create the required arguments...
! arguments = CreateArgumentArray(name, definition, resolvedValues, factoryMethod, out unsatisfiedDependencyExceptionData);
! if (arguments == null)
{
! // if we failed to match this method, keep
! // trying new overloaded factory methods...
! continue;
}
}
// if we get here, we found a factory method...
***************
*** 1100,1108 ****
/// given the resolved constructor arguments values.
/// </summary>
! private object[] CreateArgumentArray(string name, RootObjectDefinition definition,
! ConstructorArgumentValues resolvedValues, MethodBase methodOrCtor)
{
string methodType = (methodOrCtor is ConstructorInfo) ? "constructor" : "factory method";
!
ParameterInfo[] argTypes = methodOrCtor.GetParameters();
object[] args = new object[argTypes.Length];
--- 1099,1110 ----
/// 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 object[] CreateArgumentArray(string name, RootObjectDefinition definition,
! ConstructorArgumentValues resolvedValues, MethodBase methodOrCtor, out UnsatisfiedDependencyExceptionData unsatisfiedDependencyExceptionData)
{
string methodType = (methodOrCtor is ConstructorInfo) ? "constructor" : "factory method";
! unsatisfiedDependencyExceptionData = null;
ParameterInfo[] argTypes = methodOrCtor.GetParameters();
object[] args = new object[argTypes.Length];
***************
*** 1130,1137 ****
catch (TypeMismatchException ex)
{
! throw new UnsatisfiedDependencyException(definition.ResourceDescription, name, j, parameterType,
! String.Format(CultureInfo.InvariantCulture,
! "Could not convert {0} argument value [{1}] to required type [{2}] : {3}",
! methodType, valueHolder.Value, parameterType, ex.Message));
}
}
--- 1132,1143 ----
catch (TypeMismatchException ex)
{
! string errorMessage = String.Format(CultureInfo.InvariantCulture,
! "Could not convert {0} argument value [{1}] to required type [{2}] : {3}",
! methodType, valueHolder.Value,
! parameterType, ex.Message);
! unsatisfiedDependencyExceptionData = new UnsatisfiedDependencyExceptionData(j,parameterType, errorMessage);
!
!
! return null;
}
}
***************
*** 1140,1159 ****
if (definition.ResolvedAutowireMode != AutoWiringMode.Constructor)
{
! throw new UnsatisfiedDependencyException(definition.ResourceDescription, name, j, parameterType,
! String.Format(CultureInfo.InvariantCulture,
! "Ambiguous {0} argument types - " +
! "Did you specify the correct object references as {0} arguments?",
! methodType));
}
IDictionary matchingObjects = FindMatchingObjects(parameterType);
if (matchingObjects == null || matchingObjects.Count != 1)
{
! throw new UnsatisfiedDependencyException(definition.ResourceDescription, name, j, parameterType,
! String.Format(CultureInfo.InvariantCulture,
! "There are '{0}' objects of type [{1}] for autowiring "
! + "{2}. There should have been exactly 1 to be able to "
! + "autowire the '{3}' argument on the {2} of object '{4}'.",
! (matchingObjects == null ? 0 : matchingObjects.Count),
! parameterType, methodType, parameterName, name));
}
DictionaryEntry entry = (DictionaryEntry)ObjectUtils.EnumerateFirstElement(matchingObjects);
--- 1146,1174 ----
if (definition.ResolvedAutowireMode != AutoWiringMode.Constructor)
{
! string errorMessage = String.Format(CultureInfo.InvariantCulture,
! "Ambiguous {0} argument types - " +
! "Did you specify the correct object references as {0} arguments?",
! methodType);
! unsatisfiedDependencyExceptionData = new UnsatisfiedDependencyExceptionData(j, parameterType, errorMessage);
!
! return null;
}
IDictionary matchingObjects = FindMatchingObjects(parameterType);
if (matchingObjects == null || matchingObjects.Count != 1)
{
! string errorMessage = String.Format(CultureInfo.InvariantCulture,
! "There are '{0}' objects of type [{1}] for autowiring "
! +
! "{2}. There should have been exactly 1 to be able to "
! +
! "autowire the '{3}' argument on the {2} of object '{4}'.",
! (matchingObjects == null
! ? 0
! : matchingObjects.Count),
! parameterType, methodType,
! parameterName, name);
! unsatisfiedDependencyExceptionData = new UnsatisfiedDependencyExceptionData(j, parameterType, errorMessage);
!
! return null;
}
DictionaryEntry entry = (DictionaryEntry)ObjectUtils.EnumerateFirstElement(matchingObjects);
***************
*** 1265,1311 ****
object[] argsToUse = null;
int weighting = Int32.MaxValue;
for (int i = 0; i < constructors.Length; ++i)
{
! try
{
! ConstructorInfo constructor = constructors[i];
! if (constructorToUse != null &&
! constructorToUse.GetParameters().Length > constructor.GetParameters().Length)
! {
! // already found greedy constructor that can be satisfied, so
! // don't look any further, there are only less greedy constructors left...
! break;
! }
!
! object[] args = CreateArgumentArray(name, definition, argumentValues, constructor);
!
! int typeDiffWeight = AutowireUtils.GetTypeDifferenceWeight(constructor.GetParameters(), args);
! if (typeDiffWeight < weighting)
! {
! constructorToUse = constructor;
! argsToUse = args;
! weighting = typeDiffWeight;
! }
}
- catch (UnsatisfiedDependencyException ex)
- {
- #region Instrumentation
-
- if (log.IsDebugEnabled)
- {
- log.Debug("Ignoring constructor [" + constructors[i] + "] of object '" + name + "': could not satisfy dependencies. Detail: "
- + ex.Message);
- }
-
- #endregion
if (i == constructors.Length - 1 && constructorToUse == null)
{
! // all constructors tried...
! throw;
}
! // swallow and try next constructor...
}
}
if (constructorToUse == null)
{
--- 1280,1320 ----
object[] argsToUse = null;
int weighting = Int32.MaxValue;
+ UnsatisfiedDependencyExceptionData unsatisfiedDependencyExceptionData = null;
for (int i = 0; i < constructors.Length; ++i)
{
! unsatisfiedDependencyExceptionData = null;
! ConstructorInfo constructor = constructors[i];
! if (constructorToUse != null &&
! constructorToUse.GetParameters().Length > constructor.GetParameters().Length)
{
! // already found greedy constructor that can be satisfied, so
! // don't look any further, there are only less greedy constructors left...
! break;
}
+ object[] args = CreateArgumentArray(name, definition, argumentValues, constructor, out unsatisfiedDependencyExceptionData);
+ if (args == null)
+ {
if (i == constructors.Length - 1 && constructorToUse == null)
{
! throw new UnsatisfiedDependencyException(definition.ResourceDescription,
! name,
! unsatisfiedDependencyExceptionData.ParameterIndex,
! unsatisfiedDependencyExceptionData.ParameterType,
! unsatisfiedDependencyExceptionData.ErrorMessage);
}
! // try next constructor...
! continue;
! }
!
! int typeDiffWeight = AutowireUtils.GetTypeDifferenceWeight(constructor.GetParameters(), args);
! if (typeDiffWeight < weighting)
! {
! constructorToUse = constructor;
! argsToUse = args;
! weighting = typeDiffWeight;
}
}
+
if (constructorToUse == null)
{
***************
*** 2362,2364 ****
--- 2371,2402 ----
#endregion
}
+
+ internal class UnsatisfiedDependencyExceptionData
+ {
+ private int parameterIndex;
+ private Type parameterType;
+ private string errorMessage;
+
+ public UnsatisfiedDependencyExceptionData(int parameterIndex, Type parameterType, string errorMessage)
+ {
+ this.parameterIndex = parameterIndex;
+ this.parameterType = parameterType;
+ this.errorMessage = errorMessage;
+ }
+
+ public int ParameterIndex
+ {
+ get { return parameterIndex; }
+ }
+
+ public Type ParameterType
+ {
+ get { return parameterType; }
+ }
+
+ public string ErrorMessage
+ {
+ get { return errorMessage; }
+ }
+ }
}
|