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.