65.9K
CodeProject is changing. Read more.
Home

Instantiating an SqlException

starIconstarIconstarIconstarIconstarIcon

5.00/5 (3 votes)

Apr 11, 2011

CPOL
viewsIcon

30149

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.