From 483b0ef84b7af7a4582e5d618348c58c504e2324 Mon Sep 17 00:00:00 2001 From: Mark Rendle Date: Sun, 7 Jan 2018 18:37:20 +0000 Subject: [PATCH] Add Dapper implementation --- .../Beeline.AspNetCoreBenchmarks.csproj | 2 + .../Data/BeelineDb.cs | 2 +- .../Data/DapperDb.cs | 40 +++++++++++++ .../Data/World.cs | 12 ++++ .../SingleQueryBeelineMiddleware.cs | 4 +- .../Middleware/SingleQueryDapperMiddleware.cs | 56 +++++++++++++++++++ .../Beeline.AspNetCoreBenchmarks/Startup.cs | 2 + 7 files changed, 114 insertions(+), 4 deletions(-) create mode 100644 samples/Beeline.AspNetCoreBenchmarks/Data/DapperDb.cs create mode 100644 samples/Beeline.AspNetCoreBenchmarks/Data/World.cs create mode 100644 samples/Beeline.AspNetCoreBenchmarks/Middleware/SingleQueryDapperMiddleware.cs diff --git a/samples/Beeline.AspNetCoreBenchmarks/Beeline.AspNetCoreBenchmarks.csproj b/samples/Beeline.AspNetCoreBenchmarks/Beeline.AspNetCoreBenchmarks.csproj index 0e21903..a551be1 100644 --- a/samples/Beeline.AspNetCoreBenchmarks/Beeline.AspNetCoreBenchmarks.csproj +++ b/samples/Beeline.AspNetCoreBenchmarks/Beeline.AspNetCoreBenchmarks.csproj @@ -9,8 +9,10 @@ Microsoft.NETCore.App + + diff --git a/samples/Beeline.AspNetCoreBenchmarks/Data/BeelineDb.cs b/samples/Beeline.AspNetCoreBenchmarks/Data/BeelineDb.cs index 188e8cd..4e5b377 100644 --- a/samples/Beeline.AspNetCoreBenchmarks/Data/BeelineDb.cs +++ b/samples/Beeline.AspNetCoreBenchmarks/Data/BeelineDb.cs @@ -49,7 +49,7 @@ public async Task LoadSingleQueryRow(byte[] buffer, CancellationToken ct = private static DbCommand CreateSingleQueryCommand(DbConnection db, int id) { var cmd = db.CreateCommand(); - cmd.CommandText = "SELECT id, randomnumber FROM world WHERE id = @id"; + cmd.CommandText = @"SELECT id ""Id"", randomnumber ""RandomNumber"" FROM world WHERE id = @id"; var idParameter = cmd.CreateParameter(); idParameter.ParameterName = "id"; idParameter.DbType = DbType.Int32; diff --git a/samples/Beeline.AspNetCoreBenchmarks/Data/DapperDb.cs b/samples/Beeline.AspNetCoreBenchmarks/Data/DapperDb.cs new file mode 100644 index 0000000..8e9c145 --- /dev/null +++ b/samples/Beeline.AspNetCoreBenchmarks/Data/DapperDb.cs @@ -0,0 +1,40 @@ +using System.Data.Common; +using System.Threading.Tasks; +using Beeline.AspNetCoreBenchmarks.Configuration; +using Dapper; +using Microsoft.Extensions.Options; + +namespace Beeline.AspNetCoreBenchmarks.Data +{ + public class DapperDb + { + private readonly IRandom _random; + private readonly DbProviderFactory _dbProviderFactory; + private readonly string _connectionString; + + public DapperDb(IRandom random, DbProviderFactory dbProviderFactory, IOptions appSettings) + { + _random = random; + _dbProviderFactory = dbProviderFactory; + _connectionString = appSettings.Value.ConnectionString; + } + + public async Task LoadSingleQueryRow() + { + using (var db = _dbProviderFactory.CreateConnection()) + { + db.ConnectionString = _connectionString; + + // Note: Don't need to open connection if only doing one thing; let dapper do it + return await ReadSingleRow(db); + } + } + + async Task ReadSingleRow(DbConnection db) + { + return await db.QueryFirstOrDefaultAsync( + "SELECT id, randomnumber FROM world WHERE id = @Id", + new { Id = _random.Next(1, 10001) }); + } + } +} \ No newline at end of file diff --git a/samples/Beeline.AspNetCoreBenchmarks/Data/World.cs b/samples/Beeline.AspNetCoreBenchmarks/Data/World.cs new file mode 100644 index 0000000..fb16bdb --- /dev/null +++ b/samples/Beeline.AspNetCoreBenchmarks/Data/World.cs @@ -0,0 +1,12 @@ +using JetBrains.Annotations; + +namespace Beeline.AspNetCoreBenchmarks.Data +{ + [UsedImplicitly] + public class World + { + public int Id { get; set; } + + public int RandomNumber { get; set; } + } +} \ No newline at end of file diff --git a/samples/Beeline.AspNetCoreBenchmarks/Middleware/SingleQueryBeelineMiddleware.cs b/samples/Beeline.AspNetCoreBenchmarks/Middleware/SingleQueryBeelineMiddleware.cs index ff93ea3..29f91fc 100644 --- a/samples/Beeline.AspNetCoreBenchmarks/Middleware/SingleQueryBeelineMiddleware.cs +++ b/samples/Beeline.AspNetCoreBenchmarks/Middleware/SingleQueryBeelineMiddleware.cs @@ -5,8 +5,6 @@ using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; -using Newtonsoft.Json; -using Newtonsoft.Json.Serialization; namespace Beeline.AspNetCoreBenchmarks.Middleware { @@ -48,7 +46,7 @@ public async Task Invoke(HttpContext httpContext) } } - public static class SingleQueryDapperMiddlewareExtensions + public static class SingleQueryBeelineMiddlewareExtensions { public static IApplicationBuilder UseSingleQueryBeeline(this IApplicationBuilder builder) { diff --git a/samples/Beeline.AspNetCoreBenchmarks/Middleware/SingleQueryDapperMiddleware.cs b/samples/Beeline.AspNetCoreBenchmarks/Middleware/SingleQueryDapperMiddleware.cs new file mode 100644 index 0000000..d21b84c --- /dev/null +++ b/samples/Beeline.AspNetCoreBenchmarks/Middleware/SingleQueryDapperMiddleware.cs @@ -0,0 +1,56 @@ +using System; +using System.Threading.Tasks; +using Beeline.AspNetCoreBenchmarks.Data; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; + +namespace Beeline.AspNetCoreBenchmarks.Middleware +{ + public class SingleQueryDapperMiddleware + { + private static readonly PathString _path = new PathString("/db/dapper"); + private static readonly JsonSerializerSettings _jsonSettings = new JsonSerializerSettings + { + ContractResolver = new CamelCasePropertyNamesContractResolver() + }; + + private readonly RequestDelegate _next; + + public SingleQueryDapperMiddleware(RequestDelegate next) + { + _next = next; + } + + public async Task Invoke(HttpContext httpContext) + { + if (httpContext.Request.Path.StartsWithSegments(_path, StringComparison.Ordinal)) + { + var db = httpContext.RequestServices.GetService(); + var row = await db.LoadSingleQueryRow(); + + var result = JsonConvert.SerializeObject(row, _jsonSettings); + + httpContext.Response.StatusCode = StatusCodes.Status200OK; + httpContext.Response.ContentType = "application/json"; + httpContext.Response.ContentLength = result.Length; + + await httpContext.Response.WriteAsync(result); + + return; + } + + await _next(httpContext); + } + } + + public static class SingleQueryDapperMiddlewareExtensions + { + public static IApplicationBuilder UseSingleQueryDapper(this IApplicationBuilder builder) + { + return builder.UseMiddleware(); + } + } +} \ No newline at end of file diff --git a/samples/Beeline.AspNetCoreBenchmarks/Startup.cs b/samples/Beeline.AspNetCoreBenchmarks/Startup.cs index 121184d..b71b61f 100644 --- a/samples/Beeline.AspNetCoreBenchmarks/Startup.cs +++ b/samples/Beeline.AspNetCoreBenchmarks/Startup.cs @@ -34,10 +34,12 @@ public void ConfigureServices(IServiceCollection services) services.AddSingleton(); services.AddSingleton(NpgsqlFactory.Instance); services.AddSingleton(); + services.AddSingleton(); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { + app.UseSingleQueryDapper(); app.UseSingleQueryBeeline(); } }