Description
There are a couple of third party libraries (including one I'm working on...) which attempt to add functionality to the SQL execution pipeline, using custom drivers. The reason could be to add profiling, as in Glimpse or MiniProfiler, or to add resiliency, as in NHibernate.SqlAzure.
Often this is done using wrapping implementations of DbCommand, DbConnection etc.
This works reasonably well for simple scenarios, but as soon as batching is involved, and it often is, things become problematic. Understandably, the batchers often work with the DB specific implementations of DbCommand etc., but when a wrapped command "leaks" into the batcher, things go awry.
This is either not handled at all, as in Glimpse (https://github.com/stevenlauwers22/Glimpse.NHibernate#known-bugs-and-limitations), which instructs you to completely disable batching, or by using complete reimplementations of the batchers, as in https://github.com/MRCollective/NHibernate.SqlAzure/blob/master/NHibernate5.SqlAzure/ReliableSqlClientBatchingBatcher.cs . The latter is made a bit more complex, since AbstractBatcher is rather closed.
The problem could be alleviated, if drivers were allowed to provide the means to unwrap (and possibly wrap) instances to the innermost implementation type. An IWrappingDriver (or IDriver itself) could provide e.g UnwrapDbCommand, which should be used whenever the root type is needed. I've tried this in a test branch, and it works well (I've run all tests in NHibernate.Tests through my custom IDriver).
Using the wrapping strategy is rather powerful, and it allows the integration with other libraries which takes this route (EnterpriseLibrary.TransientFaultHandling.Data with its ReliableSqlCommand and Glimpse with its GlimpseDbCommand).
Another option is of course to always delegate certain method calls on SqlCommand etc. to a strategy implementation.
interface IDbCommandExecutionStrategy {
int ExecuteNonQuery(DbCommand command);
...
}
interface IDbConnectionExecutionStrategy {
int Open(DbConnection command);
...
}
etc.