public static void Throw(string exceptionKey, object[] constructorArgs, Exception innerException, params object[] messageArgs) { ArgumentHelper.AssertNotNull(exceptionKey, "exceptionKey"); //first we need to find the type from which we were invoked - this is used as a grouping mechanism in the XML config file Type invokingType = null; int skipFrames = 1; while (true) { StackFrame stackFrame = new StackFrame(skipFrames); Debug.Assert(stackFrame.GetMethod() != null); if (stackFrame.GetMethod().DeclaringType != typeof(ExceptionHelper)) { invokingType = stackFrame.GetMethod().DeclaringType; break; } ++skipFrames; } XmlDocument exceptionInfo = GetExceptionInfo(invokingType.Assembly); string xpath = string.Concat("/exceptionHelper/exceptionGroup[@type=\"", invokingType.FullName, "\"]/exception[@key=\"", exceptionKey, "\"]"); XmlNode exceptionNode = exceptionInfo.SelectSingleNode(xpath); if (exceptionNode == null) { throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "The exception details for key '{0}' could not be found (they should be under '{1}')", exceptionKey, xpath)); } XmlAttribute typeAttribute = exceptionNode.Attributes[_typeAttributeName]; if (typeAttribute == null) { throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "The '{0}' attribute could not be found for exception with key '{1}'", _typeAttributeName, exceptionKey)); } Type type = Type.GetType(typeAttribute.Value); if (type == null) { throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Type '{0}' could not be loaded for exception with key '{1}'", typeAttribute.Value, exceptionKey)); } if (!typeof(Exception).IsAssignableFrom(type)) { throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Type '{0}' for exception with key '{1}' does not inherit from '{2}'", type.FullName, exceptionKey, typeof(Exception).FullName)); } string message = exceptionNode.InnerText.Trim(); if ((messageArgs != null) && (messageArgs.Length > 0)) { message = string.Format(CultureInfo.InvariantCulture, message, messageArgs); } List <object> constructorArgsList = new List <object>(); //message is always first constructorArgsList.Add(message); //next, any additional constructor args if (constructorArgs != null) { constructorArgsList.AddRange(constructorArgs); } //finally, the inner exception, if any if (innerException != null) { constructorArgsList.Add(innerException); } object[] constructorArgsArr = constructorArgsList.ToArray(); BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance; object state; ConstructorInfo constructor = null; try { constructor = (ConstructorInfo)Type.DefaultBinder.BindToMethod(bindingFlags, type.GetConstructors(bindingFlags), ref constructorArgsArr, null, null, null, out state); } catch (MissingMethodException) { //swallow and deal with below } if (constructor == null) { throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "An appropriate constructor could not be found for exception type '{0}, for exception with key '{1}'", type.FullName, exceptionKey)); } //create the exception instance Exception e = (Exception)constructor.Invoke(constructorArgsArr); //finally, throw the exception throw e; }