From 85e7500823badb78c6290ecc1208237517d62551 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B2=88=E6=98=9F=E7=B9=81?= Date: Wed, 11 Oct 2023 18:41:56 +0800 Subject: [PATCH 1/2] feat: add generic map methods --- .../CqrsRouteMapper.cs | 43 ++++++++++++++++++ .../Program.cs | 5 +++ .../CqrsRouteMapperTests.cs | 45 +++++++++++++++++++ 3 files changed, 93 insertions(+) diff --git a/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CqrsRouteMapper.cs b/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CqrsRouteMapper.cs index 5a2da4d..f968a22 100644 --- a/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CqrsRouteMapper.cs +++ b/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CqrsRouteMapper.cs @@ -4,6 +4,7 @@ using Cnblogs.Architecture.Ddd.Cqrs.Abstractions; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Routing.Patterns; @@ -206,6 +207,20 @@ public static IEndpointConventionBuilder MapCommand( return app.MapPutCommand(route, handler); } + /// + /// Map a command API, using POST method and get command data from request body. + /// + /// + /// The route template. + /// The type of command. + /// + public static IEndpointConventionBuilder MapPostCommand( + this IEndpointRouteBuilder app, + [StringSyntax("Route")] string route) + { + return app.MapPostCommand(route, ([FromBody] TCommand command) => command); + } + /// /// Map a command API, using POST method. /// @@ -222,6 +237,20 @@ public static IEndpointConventionBuilder MapPostCommand( return app.MapPost(route, handler).AddEndpointFilter(); } + /// + /// Map a command API, using PUT method and get command data from request body. + /// + /// + /// The route template. + /// The type of command. + /// + public static IEndpointConventionBuilder MapPutCommand( + this IEndpointRouteBuilder app, + [StringSyntax("Route")] string route) + { + return app.MapPutCommand(route, ([FromBody] TCommand command) => command); + } + /// /// Map a command API, using PUT method. /// @@ -238,6 +267,20 @@ public static IEndpointConventionBuilder MapPutCommand( return app.MapPut(route, handler).AddEndpointFilter(); } + /// + /// Map a command API, using DELETE method and get command from route/query parameters. + /// + /// + /// The route template. + /// The type of command. + /// + public static IEndpointConventionBuilder MapDeleteCommand( + this IEndpointRouteBuilder app, + [StringSyntax("Route")] string route) + { + return app.MapDeleteCommand(route, ([AsParameters] TCommand command) => command); + } + /// /// Map a command API, using DELETE method. /// diff --git a/test/Cnblogs.Architecture.IntegrationTestProject/Program.cs b/test/Cnblogs.Architecture.IntegrationTestProject/Program.cs index 9adca7b..e6201dc 100644 --- a/test/Cnblogs.Architecture.IntegrationTestProject/Program.cs +++ b/test/Cnblogs.Architecture.IntegrationTestProject/Program.cs @@ -45,6 +45,11 @@ (int id, UpdatePayload payload) => new UpdateCommand(id, payload.NeedValidationError, payload.NeedExecutionError)); v1.MapCommand("strings/{id:int}"); +// generic command map +v1.MapPostCommand("generic-map/strings"); +v1.MapPutCommand("generic-map/strings"); +v1.MapDeleteCommand("generic-map/strings/{id:int}"); + app.Run(); namespace Cnblogs.Architecture.IntegrationTestProject diff --git a/test/Cnblogs.Architecture.IntegrationTests/CqrsRouteMapperTests.cs b/test/Cnblogs.Architecture.IntegrationTests/CqrsRouteMapperTests.cs index 1eb6f88..e37230e 100644 --- a/test/Cnblogs.Architecture.IntegrationTests/CqrsRouteMapperTests.cs +++ b/test/Cnblogs.Architecture.IntegrationTests/CqrsRouteMapperTests.cs @@ -2,6 +2,7 @@ using System.Net.Http.Json; using Cnblogs.Architecture.Ddd.Infrastructure.Abstractions; using Cnblogs.Architecture.IntegrationTestProject; +using Cnblogs.Architecture.IntegrationTestProject.Application.Commands; using FluentAssertions; using Microsoft.AspNetCore.Mvc.Testing; @@ -132,4 +133,48 @@ public async Task GetItem_MapHeadAndGet_SuccessAsync() // Assert responses.Should().Match(x => x.All(y => y.IsSuccessStatusCode)); } + + [Fact] + public async Task PostItem_GenericMap_SuccessAsync() + { + // Arrange + var builder = new WebApplicationFactory(); + + // Act + var response = await builder.CreateClient().PostAsJsonAsync( + "/api/v1/generic-map/strings", + new CreateCommand(false, "data")); + + // Assert + response.Should().BeSuccessful(); + } + + [Fact] + public async Task PutItem_GenericMap_SuccessAsync() + { + // Arrange + var builder = new WebApplicationFactory(); + + // Act + var response = await builder.CreateClient().PutAsJsonAsync( + "/api/v1/generic-map/strings", + new UpdateCommand(1, false, false)); + + // Assert + response.Should().BeSuccessful(); + } + + [Fact] + public async Task DeleteCommand_GenericMap_SuccessAsync() + { + // Arrange + var builder = new WebApplicationFactory(); + + // Act + var queryBuilder = new QueryStringBuilder().Add("needError", false); + var response = await builder.CreateClient().DeleteAsync("/api/v1/generic-map/strings/1" + queryBuilder.Build()); + + // Assert + response.Should().BeSuccessful(); + } } From 1ba933409c8049aca1eeddc974c7730675129b42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B2=88=E6=98=9F=E7=B9=81?= Date: Wed, 11 Oct 2023 18:44:35 +0800 Subject: [PATCH 2/2] chore: upgrade packages --- .../Cnblogs.Architecture.Ddd.Cqrs.AspNetCore.csproj | 2 +- ...blogs.Architecture.Ddd.Infrastructure.EntityFramework.csproj | 2 +- .../Cnblogs.Architecture.Ddd.Infrastructure.MongoDb.csproj | 2 +- .../Cnblogs.Architecture.IntegrationTests.csproj | 2 +- .../Cnblogs.Architecture.UnitTests.csproj | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore.csproj b/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore.csproj index 61ced12..2b06027 100644 --- a/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore.csproj +++ b/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore.csproj @@ -7,7 +7,7 @@ - + diff --git a/src/Cnblogs.Architecture.Ddd.Infrastructure.EntityFramework/Cnblogs.Architecture.Ddd.Infrastructure.EntityFramework.csproj b/src/Cnblogs.Architecture.Ddd.Infrastructure.EntityFramework/Cnblogs.Architecture.Ddd.Infrastructure.EntityFramework.csproj index a580a44..16789e2 100644 --- a/src/Cnblogs.Architecture.Ddd.Infrastructure.EntityFramework/Cnblogs.Architecture.Ddd.Infrastructure.EntityFramework.csproj +++ b/src/Cnblogs.Architecture.Ddd.Infrastructure.EntityFramework/Cnblogs.Architecture.Ddd.Infrastructure.EntityFramework.csproj @@ -9,7 +9,7 @@ - + diff --git a/src/Cnblogs.Architecture.Ddd.Infrastructure.MongoDb/Cnblogs.Architecture.Ddd.Infrastructure.MongoDb.csproj b/src/Cnblogs.Architecture.Ddd.Infrastructure.MongoDb/Cnblogs.Architecture.Ddd.Infrastructure.MongoDb.csproj index d0f7906..2234b90 100644 --- a/src/Cnblogs.Architecture.Ddd.Infrastructure.MongoDb/Cnblogs.Architecture.Ddd.Infrastructure.MongoDb.csproj +++ b/src/Cnblogs.Architecture.Ddd.Infrastructure.MongoDb/Cnblogs.Architecture.Ddd.Infrastructure.MongoDb.csproj @@ -10,7 +10,7 @@ - + diff --git a/test/Cnblogs.Architecture.IntegrationTests/Cnblogs.Architecture.IntegrationTests.csproj b/test/Cnblogs.Architecture.IntegrationTests/Cnblogs.Architecture.IntegrationTests.csproj index 55ac1c9..2bff262 100644 --- a/test/Cnblogs.Architecture.IntegrationTests/Cnblogs.Architecture.IntegrationTests.csproj +++ b/test/Cnblogs.Architecture.IntegrationTests/Cnblogs.Architecture.IntegrationTests.csproj @@ -1,7 +1,7 @@ - + diff --git a/test/Cnblogs.Architecture.UnitTests/Cnblogs.Architecture.UnitTests.csproj b/test/Cnblogs.Architecture.UnitTests/Cnblogs.Architecture.UnitTests.csproj index 3bb0d4e..b3b1c42 100644 --- a/test/Cnblogs.Architecture.UnitTests/Cnblogs.Architecture.UnitTests.csproj +++ b/test/Cnblogs.Architecture.UnitTests/Cnblogs.Architecture.UnitTests.csproj @@ -1,7 +1,7 @@ - +