示例#1
0
        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;
        }