/// <summary> /// Dynamically Invokes either a constructor, instance or static method as supplied with the /// provided arguments an instance as appropriate. /// </summary> /// <param name = "method">The method to invoke.</param> /// <param name = "parameters">The parameters to use.</param> /// <param name = "instance">The instance to invoke the method against if it is an instance method.</param> /// <returns>The results of the instance invocation.</returns> private static object InternalDynaInvoke(MethodBase method, object[] parameters, object instance = null) { try { if (typeof(ConstructorInfo).IsAssignableFrom(method.GetType())) { return(method.As <ConstructorInfo>().Invoke(parameters)); } if (instance.IsNotNull() && method.IsStatic) { return(method.Invoke(null, TestHelp.Array(instance).Union(parameters).ToArray())); } else { return(method.Invoke(instance, parameters)); } } catch (TargetInvocationException ex) { // An exception occurring inside of the Target when Invoked via // reflection will get caught and rethrown as a TargetInvocationException // In these cases we want to have the inner exception sent up the // stack so that the actual exception is presented to the test case. // This code removes the TargetInvocationException and "fixes" the // call stack to match. // Use reflections to get the inner field that holds the stack inside // of an exception. FieldInfo remoteStackTrace = typeof(Exception).GetField("_remoteStackTraceString", BindingFlags.Instance | BindingFlags.NonPublic); // Set the InnerException._remoteStackTraceString // to the current InnerException.StackTrace // This "fixes" the stack trace so that it does not appear to originate // from here when we re-throw the inner exception. remoteStackTrace.SetValue(ex.InnerException, ex.InnerException.StackTrace + Environment.NewLine); // Re-throw the inner exception. throw ex.InnerException; } }
private static int CompareTypeAssignments(ParameterInfo[] parameters, object[] values, Type nullType, Type[] typeParameters) { TestHelp.DoNothing(typeParameters); int paramCount = parameters != null?parameters.Count() : 0; int objCount = values != null?values.Count() : 0; if (paramCount == 0 && objCount == 0) { return(int.MaxValue); } int max = Math.Max(paramCount, objCount); int retval = 0; ParameterInfo paramsParameter = null; for (int i = 0; i < max; i++) { if (i < paramCount && i < objCount) { ParameterInfo info = parameters[i]; if (info.GetCustomAttributes(true).Where(a => a.GetType().IsAssignableFrom(typeof(ParamArrayAttribute))).Count() > 0) { paramsParameter = info; } Type infoType = info.ParameterType; object obj = values[i]; Type objType = nullType; if (obj != null) { objType = obj.GetType(); } // If the object type is exactly the same as the infoType we have an exact match. if (objType == infoType) { retval += 6; continue; } // Check to see if method parameter is of type T. if (infoType.IsGenericParameter) { Type[] genericParameterConstraints = infoType.GetGenericParameterConstraints(); if (genericParameterConstraints.Count() == 0 || genericParameterConstraints.Any(constraint => constraint.IsAssignableFrom(objType))) { retval += 3; } } else if (infoType.IsArray && objType.IsArray) { Type infoElementType = infoType.GetElementType(); Type objElementType = objType.GetElementType(); if (infoElementType.ContainsGenericParameters) { Type[] genericParameterConstraints = infoElementType.GetGenericParameterConstraints(); if (genericParameterConstraints.Count() == 0 || genericParameterConstraints.Any(constraint => constraint.IsAssignableFrom(objElementType))) { retval += 3; } } } else if (infoType.IsArray && paramsParameter.IsNotNull()) { Type infoElementType = infoType.GetElementType(); Type objElementType = objType; if (infoElementType.ContainsGenericParameters) { Type[] genericParameterConstraints = infoElementType.GetGenericParameterConstraints(); if (genericParameterConstraints.Count() == 0 || genericParameterConstraints.Any(constraint => constraint.IsAssignableFrom(objElementType))) { retval += 3; } } } else { if (infoType == objType) { retval += 6; } else if (infoType.IsAssignableFrom(objType)) { retval += 5; } else if (objType.IsAssignableFrom(infoType)) { retval += 5; } else if (infoType.ContainsGenericParameters) { // Above check to see if method parameter is of type C<T>/C<U,V>. // Since infoType is obtained from compile time information // it does not have T resolved. Hence we use infoType.Name // which is in format C'1. // infoType.FullName is empty therefore it is not used. if (infoType.Name == objType.Name) { retval += 3; } } else if (typeof(IEnumerable).IsAssignableFrom(infoType) && typeof(IEnumerable).IsAssignableFrom(objType)) { retval += 1; } } } else if (i >= paramCount && i < objCount && paramsParameter.IsNotNull()) { // params function, this method could be covered by the params array. break; } else { // parameter count is unequal so return the lowest score. retval = 0; break; } } return(retval); }