From d98024cdac85c23b1e2371ea697f03e4f0913727 Mon Sep 17 00:00:00 2001 From: danielmarbach Date: Tue, 30 May 2023 12:25:26 +0200 Subject: [PATCH] Use resource filter instead of middleware --- .../WebApplication/MessageSessionFilter.cs | 27 ++++++++++ .../MessageSessionMiddleware.cs | 24 --------- .../WebApplication/Program.cs | 54 +++++++++++++------ .../WebApplication/SendMessageController.cs | 14 ++++- 4 files changed, 79 insertions(+), 40 deletions(-) create mode 100644 samples/transactional-session/aspnetcore-webapi/SqlPersistenceTS_6/WebApplication/MessageSessionFilter.cs delete mode 100644 samples/transactional-session/aspnetcore-webapi/SqlPersistenceTS_6/WebApplication/MessageSessionMiddleware.cs diff --git a/samples/transactional-session/aspnetcore-webapi/SqlPersistenceTS_6/WebApplication/MessageSessionFilter.cs b/samples/transactional-session/aspnetcore-webapi/SqlPersistenceTS_6/WebApplication/MessageSessionFilter.cs new file mode 100644 index 00000000000..7fd6d0e9d60 --- /dev/null +++ b/samples/transactional-session/aspnetcore-webapi/SqlPersistenceTS_6/WebApplication/MessageSessionFilter.cs @@ -0,0 +1,27 @@ +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Filters; +using Microsoft.Extensions.DependencyInjection; +using NServiceBus.TransactionalSession; + +public sealed class MessageSessionFilter : IAsyncResourceFilter +{ + public async Task OnResourceExecutionAsync(ResourceExecutingContext context, ResourceExecutionDelegate next) + { + context.HttpContext.Items.Add(nameof(MessageSessionFilter), null); + + var session = context.HttpContext.RequestServices.GetRequiredService(); + await session.Open(new SqlPersistenceOpenSessionOptions()); + + await next(); + + await session.Commit(); + } +} + +public sealed class RequiresTransactionalSession : ServiceFilterAttribute +{ + public RequiresTransactionalSession() : base(typeof(MessageSessionFilter)) + { + } +} \ No newline at end of file diff --git a/samples/transactional-session/aspnetcore-webapi/SqlPersistenceTS_6/WebApplication/MessageSessionMiddleware.cs b/samples/transactional-session/aspnetcore-webapi/SqlPersistenceTS_6/WebApplication/MessageSessionMiddleware.cs deleted file mode 100644 index 28420742e5c..00000000000 --- a/samples/transactional-session/aspnetcore-webapi/SqlPersistenceTS_6/WebApplication/MessageSessionMiddleware.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; -using NServiceBus.TransactionalSession; - -public class MessageSessionMiddleware -{ - readonly RequestDelegate next; - - public MessageSessionMiddleware(RequestDelegate next) - { - this.next = next; - } - - #region txsession-middleware - public async Task InvokeAsync(HttpContext httpContext, ITransactionalSession session) - { - await session.Open(new SqlPersistenceOpenSessionOptions()); - - await next(httpContext); - - await session.Commit(); - } - #endregion -} \ No newline at end of file diff --git a/samples/transactional-session/aspnetcore-webapi/SqlPersistenceTS_6/WebApplication/Program.cs b/samples/transactional-session/aspnetcore-webapi/SqlPersistenceTS_6/WebApplication/Program.cs index 956da677c90..9ac9ffe17b0 100644 --- a/samples/transactional-session/aspnetcore-webapi/SqlPersistenceTS_6/WebApplication/Program.cs +++ b/samples/transactional-session/aspnetcore-webapi/SqlPersistenceTS_6/WebApplication/Program.cs @@ -1,6 +1,7 @@ using Microsoft.Data.SqlClient; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -10,7 +11,7 @@ using NServiceBus.TransactionalSession; public class Program -{ +{ // for SqlExpress use Data Source=.\SqlExpress;Initial Catalog=nservicebus;Integrated Security=True;Encrypt=false const string ConnectionString = @"Server=localhost,1433;Initial Catalog=nservicebus;User Id=SA;Password=yourStrong(!)Password;Encrypt=false"; @@ -48,33 +49,56 @@ public static void Main() #region txsession-ef-configuration .ConfigureServices(c => { - // Configure Entity Framework to attach to the synchronized storage session + // Configure Entity Framework to attach to the synchronized storage session when required c.AddScoped(b => { - var session = b.GetRequiredService(); - var context = new MyDataContext(new DbContextOptionsBuilder() - .UseSqlServer(session.Connection) - .Options); + var requiresSessionIntegration = true; + var contextAccessor = b.GetRequiredService(); + if (contextAccessor.HttpContext != null && !contextAccessor.HttpContext.Items.TryGetValue(nameof(MessageSessionFilter), out _)) + { + requiresSessionIntegration = false; + } - //Use the same underlying ADO.NET transaction - context.Database.UseTransaction(session.Transaction); + if (requiresSessionIntegration) + { + var session = b.GetRequiredService(); + var context = new MyDataContext(new DbContextOptionsBuilder() + .UseSqlServer(session.Connection) + .Options); - //Ensure context is flushed before the transaction is committed - session.OnSaveChanges((s) => context.SaveChangesAsync()); + //Use the same underlying ADO.NET transaction + context.Database.UseTransaction(session.Transaction); + + //Ensure context is flushed before the transaction is committed + session.OnSaveChanges((s) => context.SaveChangesAsync()); + + return context; + } + else + { + var context = new MyDataContext(new DbContextOptionsBuilder() + .UseSqlServer(ConnectionString) + .Options); + return context; + } - return context; }); }) #endregion .ConfigureWebHostDefaults(c => { - c.ConfigureServices(s => s.AddControllers()); - c.Configure(app => + c.ConfigureServices(s => { + s.AddControllers(); + #region txsession-web-configuration - app.UseMiddleware(); + s.AddScoped(); + s.AddHttpContextAccessor(); #endregion + }); + c.Configure(app => + { app.UseRouting(); app.UseEndpoints(r => r.MapControllers()); }); @@ -83,4 +107,4 @@ public static void Main() host.Run(); } -} +} \ No newline at end of file diff --git a/samples/transactional-session/aspnetcore-webapi/SqlPersistenceTS_6/WebApplication/SendMessageController.cs b/samples/transactional-session/aspnetcore-webapi/SqlPersistenceTS_6/WebApplication/SendMessageController.cs index 691370044f2..c4c85a4c168 100644 --- a/samples/transactional-session/aspnetcore-webapi/SqlPersistenceTS_6/WebApplication/SendMessageController.cs +++ b/samples/transactional-session/aspnetcore-webapi/SqlPersistenceTS_6/WebApplication/SendMessageController.cs @@ -1,6 +1,9 @@ using System; +using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; using NServiceBus.TransactionalSession; [ApiController] @@ -18,6 +21,7 @@ public SendMessageController(ITransactionalSession messageSession, MyDataContext #region txsession-controller [HttpGet] + [RequiresTransactionalSession] public async Task Get() { var id = Guid.NewGuid().ToString(); @@ -31,4 +35,12 @@ await messageSession.SendLocal(message) return $"Message with entity ID '{id}' sent to endpoint"; } #endregion -} + + #region txsession-controller-query + [HttpGet("/all")] + public async Task> GetAll() + { + return await dataContext.MyEntities.ToListAsync(); + } + #endregion +} \ No newline at end of file