I have been experimenting with a lightweight solution for handling my business logic. It consists of a vanilla ADO.NET connection that is extended with Dapper, and monitored by Glimpse.ADO. The use case for this setup will be a web application that has to process a handful of queries asynchronously per request. Below a simple implementation of my setup in an MVC controller.
public class CatsAndDogsController : Controller
{
public async Task<ActionResult> Index()
{
var fetchCatsTask = FetchCats(42);
var fetchDogsTask = FetchDogs(true);
await Task.WhenAll(fetchCatsTask, fetchDogsTask);
ViewBag.Cats = fetchCatsTask.Result;
ViewBag.Dogs = fetchDogsTask.Result;
return View();
}
public async Task<IEnumerable<Cat>> FetchCats(int breedId)
{
IEnumerable<Cat> result = null;
using (var connection = CreateAdoConnection())
{
await connection.OpenAsync();
result = await connection.QueryAsync<Cat>("SELECT * FROM Cat WHERE BreedId = @bid;", new { bid = breedId });
connection.Close();
}
return result;
}
public async Task<IEnumerable<Dog>> FetchDogs(bool isMale)
{
IEnumerable<Dog> result = null;
using (var connection = CreateAdoConnection())
{
await connection.OpenAsync();
result = await connection.QueryAsync<Dog>("SELECT * FROM Dog WHERE IsMale = @im;", new { im = isMale });
connection.Close();
}
return result;
}
public System.Data.Common.DbConnection CreateAdoConnection()
{
var sqlClientProviderFactory = System.Data.Common.DbProviderFactories.GetFactory("System.Data.SqlClient");
var dbConnection = sqlClientProviderFactory.CreateConnection();
dbConnection.ConnectionString = "SomeConnectionStringToAwesomeData";
return dbConnection;
}
}
I have some questions concerning the creation of the connection in the CreateAdoConnection()
method. I assume the following is happening behind the scenes.
The call to sqlClientProviderFactory.CreateConnection()
returns an instance of System.Data.SqlClient.SqlConnection
passed as a System.Data.Common.DbConnection
. At this point Glimpse.ADO.AlternateType.GlimpseDbProviderFactory
kicks in and wraps this connection in an instance of Glimpse.Ado.AlternateType.GlimpseDbConnection
, which is also passed as a System.Data.Common.DbConnection
. Finally, this connection is indirectly extended by the Dapper library with its query methods, among them the QueryAsync<>()
method used to fetch the cats and dogs.
The questions:
- Is the above assumption correct?
- If I use Dapper's async methods with this connection - or create a
System.Data.Common.DbCommand
with this connection'sCreateCommand()
method, and use it's async methods - will those calls internally always end up using the vanilla async implementations of these methods as Microsoft has written them forSystem.Data.SqlClient.SqlConnection
andSystem.Data.SqlClient.SqlCommand
? And not some other implementations of these methods that are actually blocking? - How much perf do I lose with this setup compared to just returning a new
System.Data.SqlClient.SqlConnection
directly? (So, without the Glimpse.ADO wrapper) - Any suggestions on improving this setup?