Instantiating an SqlException





5.00/5 (3 votes)
Using Reflection to instantiate a System.Data.SqlClient.SqlException
When I was testing my handling of
Exception
s for my database access classes, I found that I couldn't just instantiate and throw an SqlException
. An SqlException
requires a collection of SqlError
s, 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.