Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / SQL

Instantiating an SqlException

5.00/5 (3 votes)
20 Apr 2011CPOL 30K  
Using Reflection to instantiate a System.Data.SqlClient.SqlException
When I was testing my handling of Exceptions for my database access classes, I found that I couldn't just instantiate and throw an SqlException. An SqlException requires a collection of SqlErrors, and the designers must have decided that developers can't be trusted to create them properly. The result is that the SqlException, SqlError, and SqlErrorCollection classes have no public constructors.

That's no problem, of course, because we can use Reflection. The following code uses Reflection to access the private constructors of these classes.

namespace PIEBALD.Lib
{
    public static partial class SqlError
    {
        private static readonly System.Reflection.ConstructorInfo constructor;

        private static SqlError()
        {
            constructor = 
                typeof(System.Data.SqlClient.SqlError).GetConstructor
                (
                    System.Reflection.BindingFlags.NonPublic | 
                    System.Reflection.BindingFlags.Instance,
                    null,
                    new System.Type[] 
                    { 
                        typeof(int), 
                        typeof(byte), 
                        typeof(byte), 
                        typeof(string), 
                        typeof(string),
                        typeof(string), 
                        typeof(int) 
                    },
                    null
                );

            return;
        }

        public static System.Data.SqlClient.SqlError Create(
            int InfoNumber,
            byte ErrorState,
            byte ErrorClass,
            string Server,
            string ErrorMessage,
            string Procedure,
            int LineNumber
        )
        {
            return 
            (
                (System.Data.SqlClient.SqlError)constructor.Invoke
                (
                    new object[]
                    {
                        InfoNumber,
                        ErrorState,
                        ErrorClass,
                        Server,
                        ErrorMessage,
                        Procedure,
                        LineNumber
                    }
                )
            );
        }
    }

    public static partial class SqlErrorCollection
    {
        private static readonly System.Reflection.ConstructorInfo constructor;
        private static readonly System.Reflection.MethodInfo add;

        static SqlErrorCollection()
        {
            constructor = 
                typeof(System.Data.SqlClient.SqlErrorCollection).GetConstructor
                (
                    System.Reflection.BindingFlags.NonPublic | 
                    System.Reflection.BindingFlags.Instance,
                    null,
                    new System.Type[] { },
                    null
                );

            add = typeof(System.Data.SqlClient.SqlErrorCollection).GetMethod
            (
                "Add",
                System.Reflection.BindingFlags.NonPublic | 
                System.Reflection.BindingFlags.Instance
            );

            return;
        }

        public static System.Data.SqlClient.SqlErrorCollection Create(
            params System.Data.SqlClient.SqlError[] SqlErrors
        )
        {
            System.Data.SqlClient.SqlErrorCollection result = 
                (System.Data.SqlClient.SqlErrorCollection)constructor.Invoke
                (
                    new System.Type[] { }
                );

            foreach (System.Data.SqlClient.SqlError err in SqlErrors)
            {
                add.Invoke(result, new object[] { err });
            }

            return (result);
        }
    }

    public static partial class SqlException
    {
        private static readonly System.Reflection.ConstructorInfo constructor;

        static SqlException()
        {
            constructor = typeof(System.Data.SqlClient.SqlException).GetConstructor
            (
                System.Reflection.BindingFlags.NonPublic | 
                System.Reflection.BindingFlags.Instance,
                null,
                new System.Type[] 
                { 
                    typeof(string), 
                    typeof(System.Data.SqlClient.SqlErrorCollection) 
                },
                null
            );

            return;
        }

        public static System.Data.SqlClient.SqlException Create(
            string Message, 
            System.Data.SqlClient.SqlErrorCollection ErrorCollection
        )
        {
            return 
            (
                (System.Data.SqlClient.SqlException)constructor.Invoke
                (
                    new object[]
                    {
                        Message,
                        ErrorCollection
                    }
                )
            );
        }
    }
}


I'll reiterate that this is handy for unit testing Exception handling code -- I don't recommend using it in production; there shouldn't be a need to use it in production anyway.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)