From 9585d5c8c4c42cbf74453f489826c9c500accbe8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B2=88=E6=98=9F=E7=B9=81?= Date: Sun, 27 Oct 2024 15:10:21 +0800 Subject: [PATCH 1/3] feat: add long to string json converter --- .../CommandEndpointHandler.cs | 22 +---- .../ControllerOptionInjector.cs | 13 ++- .../CqrsHttpOptions.cs | 9 ++ .../CqrsHttpOptionsInjector.cs | 12 +++ .../CqrsResult.cs | 7 +- .../CqrsResultExtensions.cs | 6 +- .../LongToStringConverter.cs | 39 ++++++++ .../QueryEndpointHandler.cs | 21 ++-- .../Commands/CreateLongToStringCommand.cs | 7 ++ .../CreateLongToStringCommandHandler.cs | 16 ++++ .../Queries/GetLongToStringQuery.cs | 6 ++ .../Queries/GetLongToStringQueryHandler.cs | 13 +++ .../Controllers/TestController.cs | 26 +++-- .../Models/LongToStringModel.cs | 6 ++ .../Program.cs | 5 +- .../CustomJsonConverterTests.cs | 96 +++++++++++++++++++ 16 files changed, 255 insertions(+), 49 deletions(-) create mode 100644 src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/LongToStringConverter.cs create mode 100644 test/Cnblogs.Architecture.IntegrationTestProject/Application/Commands/CreateLongToStringCommand.cs create mode 100644 test/Cnblogs.Architecture.IntegrationTestProject/Application/Commands/CreateLongToStringCommandHandler.cs create mode 100644 test/Cnblogs.Architecture.IntegrationTestProject/Application/Queries/GetLongToStringQuery.cs create mode 100644 test/Cnblogs.Architecture.IntegrationTestProject/Application/Queries/GetLongToStringQueryHandler.cs create mode 100644 test/Cnblogs.Architecture.IntegrationTestProject/Models/LongToStringModel.cs create mode 100644 test/Cnblogs.Architecture.IntegrationTests/CustomJsonConverterTests.cs diff --git a/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CommandEndpointHandler.cs b/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CommandEndpointHandler.cs index 0b3b675..41b628c 100644 --- a/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CommandEndpointHandler.cs +++ b/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CommandEndpointHandler.cs @@ -8,21 +8,9 @@ namespace Cnblogs.Architecture.Ddd.Cqrs.AspNetCore; /// /// Execute command returned by endpoint handler, and then map command response to HTTP response. /// -public class CommandEndpointHandler : IEndpointFilter +public class CommandEndpointHandler(IMediator mediator, IOptions options) : IEndpointFilter { - private readonly IMediator _mediator; - private readonly CqrsHttpOptions _options; - - /// - /// Create a command endpoint handler. - /// - /// - /// The options for command response handling. - public CommandEndpointHandler(IMediator mediator, IOptions options) - { - _mediator = mediator; - _options = options.Value; - } + private readonly CqrsHttpOptions _options = options.Value; /// public async ValueTask InvokeAsync(EndpointFilterInvocationContext context, EndpointFilterDelegate next) @@ -40,7 +28,7 @@ public CommandEndpointHandler(IMediator mediator, IOptions opti return command; } - var response = await _mediator.Send(command); + var response = await mediator.Send(command); if (response is null) { // should not be null @@ -59,8 +47,8 @@ public CommandEndpointHandler(IMediator mediator, IOptions opti if (commandResponse is IObjectResponse objectResponse) { return context.HttpContext.Request.Headers.CqrsVersion() > 1 - ? Results.Extensions.Cqrs(response) - : Results.Ok(objectResponse.GetResult()); + ? Results.Extensions.Cqrs(response, _options.DefaultJsonSerializerOptions) + : Results.Json(objectResponse.GetResult(), _options.DefaultJsonSerializerOptions); } return Results.NoContent(); diff --git a/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/ControllerOptionInjector.cs b/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/ControllerOptionInjector.cs index b8c8d1a..2b5ebc8 100644 --- a/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/ControllerOptionInjector.cs +++ b/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/ControllerOptionInjector.cs @@ -23,8 +23,17 @@ public static void AddCqrsModelBinderProvider(this MvcOptions options) /// Add custom model binder used for CQRS, like model binder for . /// /// - public static void AddCqrsModelBinderProvider(this IMvcBuilder builder) + public static IMvcBuilder AddCqrsModelBinderProvider(this IMvcBuilder builder) { - builder.AddMvcOptions(options => options.AddCqrsModelBinderProvider()); + return builder.AddMvcOptions(options => options.AddCqrsModelBinderProvider()); + } + + /// + /// Add long to string json converter. + /// + /// . + public static IMvcBuilder AddLongToStringJsonConverter(this IMvcBuilder builder) + { + return builder.AddJsonOptions(o => o.JsonSerializerOptions.Converters.Add(new LongToStringConverter())); } } diff --git a/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CqrsHttpOptions.cs b/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CqrsHttpOptions.cs index ba5a454..71ea276 100644 --- a/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CqrsHttpOptions.cs +++ b/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CqrsHttpOptions.cs @@ -1,3 +1,4 @@ +using System.Text.Json; using Cnblogs.Architecture.Ddd.Cqrs.Abstractions; using Microsoft.AspNetCore.Http; @@ -17,4 +18,12 @@ public class CqrsHttpOptions /// Custom logic to handle error command response. /// public Func? CustomCommandErrorResponseMapper { get; set; } + + /// + /// Default json serializer options for minimal api. + /// + /// + /// For Controllers, please use builder.AddControllers().AddLongToStringJsonConverter(); + /// + public JsonSerializerOptions DefaultJsonSerializerOptions { get; set; } = new(JsonSerializerDefaults.Web); } diff --git a/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CqrsHttpOptionsInjector.cs b/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CqrsHttpOptionsInjector.cs index 4b61921..76b0246 100644 --- a/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CqrsHttpOptionsInjector.cs +++ b/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CqrsHttpOptionsInjector.cs @@ -42,4 +42,16 @@ public static CqrsInjector UseCustomCommandErrorResponseMapper( }); return injector; } + + /// + /// Serialize long to string for all json output. + /// + /// + /// + public static CqrsInjector UseLongToStringJsonConverter(this CqrsInjector injector) + { + injector.Services.Configure( + o => o.DefaultJsonSerializerOptions.Converters.Add(new LongToStringConverter())); + return injector; + } } diff --git a/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CqrsResult.cs b/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CqrsResult.cs index e391fd0..8dfe755 100644 --- a/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CqrsResult.cs +++ b/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CqrsResult.cs @@ -1,4 +1,5 @@ -using Microsoft.AspNetCore.Http; +using System.Text.Json; +using Microsoft.AspNetCore.Http; namespace Cnblogs.Architecture.Ddd.Cqrs.AspNetCore; @@ -6,12 +7,12 @@ namespace Cnblogs.Architecture.Ddd.Cqrs.AspNetCore; /// Send object as json and append X-Cqrs-Version header /// /// -public class CqrsResult(object commandResponse) : IResult +public class CqrsResult(object commandResponse, JsonSerializerOptions? options = null) : IResult { /// public Task ExecuteAsync(HttpContext httpContext) { httpContext.Response.Headers.Append("X-Cqrs-Version", "2"); - return httpContext.Response.WriteAsJsonAsync(commandResponse); + return httpContext.Response.WriteAsJsonAsync(commandResponse, options); } } diff --git a/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CqrsResultExtensions.cs b/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CqrsResultExtensions.cs index cb6a2ef..8f46e56 100644 --- a/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CqrsResultExtensions.cs +++ b/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CqrsResultExtensions.cs @@ -1,3 +1,4 @@ +using System.Text.Json; using Microsoft.AspNetCore.Http; namespace Cnblogs.Architecture.Ddd.Cqrs.AspNetCore; @@ -12,10 +13,11 @@ public static class CqrsResultExtensions /// /// /// The command response. + /// Optional json serializer options. /// - public static IResult Cqrs(this IResultExtensions extensions, object result) + public static IResult Cqrs(this IResultExtensions extensions, object result, JsonSerializerOptions? options = null) { ArgumentNullException.ThrowIfNull(extensions); - return new CqrsResult(result); + return new CqrsResult(result, options); } } diff --git a/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/LongToStringConverter.cs b/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/LongToStringConverter.cs new file mode 100644 index 0000000..6bf7781 --- /dev/null +++ b/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/LongToStringConverter.cs @@ -0,0 +1,39 @@ +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Cnblogs.Architecture.Ddd.Cqrs.AspNetCore; + +/// +/// Converter between long and string +/// +internal class LongToStringConverter : JsonConverter +{ + /// + public override long Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType != JsonTokenType.String) + { + return reader.GetInt64(); + } + + var raw = reader.GetString(); + if (string.IsNullOrWhiteSpace(raw)) + { + throw new JsonException("string is empty"); + } + + var success = long.TryParse(raw, out var parsed); + if (success == false) + { + throw new JsonException("string value can't be converted to long"); + } + + return parsed; + } + + /// + public override void Write(Utf8JsonWriter writer, long value, JsonSerializerOptions options) + { + writer.WriteStringValue(value.ToString()); + } +} diff --git a/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/QueryEndpointHandler.cs b/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/QueryEndpointHandler.cs index f16a7e7..0316557 100644 --- a/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/QueryEndpointHandler.cs +++ b/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/QueryEndpointHandler.cs @@ -1,25 +1,14 @@ using MediatR; - using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Options; namespace Cnblogs.Architecture.Ddd.Cqrs.AspNetCore; /// /// The query executor, auto send query to . /// -public class QueryEndpointHandler : IEndpointFilter +public class QueryEndpointHandler(IMediator mediator, IOptions cqrsHttpOptions) : IEndpointFilter { - private readonly IMediator _mediator; - - /// - /// Create a . - /// - /// The mediator to use. - public QueryEndpointHandler(IMediator mediator) - { - _mediator = mediator; - } - /// public async ValueTask InvokeAsync(EndpointFilterInvocationContext context, EndpointFilterDelegate next) { @@ -34,7 +23,9 @@ public QueryEndpointHandler(IMediator mediator) return query; } - var response = await _mediator.Send(query); - return response == null ? Results.NotFound() : Results.Ok(response); + var response = await mediator.Send(query); + return response == null + ? Results.NotFound() + : Results.Json(response, cqrsHttpOptions.Value.DefaultJsonSerializerOptions); } } diff --git a/test/Cnblogs.Architecture.IntegrationTestProject/Application/Commands/CreateLongToStringCommand.cs b/test/Cnblogs.Architecture.IntegrationTestProject/Application/Commands/CreateLongToStringCommand.cs new file mode 100644 index 0000000..4c139a9 --- /dev/null +++ b/test/Cnblogs.Architecture.IntegrationTestProject/Application/Commands/CreateLongToStringCommand.cs @@ -0,0 +1,7 @@ +using Cnblogs.Architecture.Ddd.Cqrs.Abstractions; +using Cnblogs.Architecture.IntegrationTestProject.Application.Errors; +using Cnblogs.Architecture.IntegrationTestProject.Models; + +namespace Cnblogs.Architecture.IntegrationTestProject.Application.Commands; + +public record CreateLongToStringCommand(long Id, bool ValidateOnly = false) : ICommand; diff --git a/test/Cnblogs.Architecture.IntegrationTestProject/Application/Commands/CreateLongToStringCommandHandler.cs b/test/Cnblogs.Architecture.IntegrationTestProject/Application/Commands/CreateLongToStringCommandHandler.cs new file mode 100644 index 0000000..830007b --- /dev/null +++ b/test/Cnblogs.Architecture.IntegrationTestProject/Application/Commands/CreateLongToStringCommandHandler.cs @@ -0,0 +1,16 @@ +using Cnblogs.Architecture.Ddd.Cqrs.Abstractions; +using Cnblogs.Architecture.IntegrationTestProject.Application.Errors; +using Cnblogs.Architecture.IntegrationTestProject.Models; + +namespace Cnblogs.Architecture.IntegrationTestProject.Application.Commands; + +public class CreateLongToStringCommandHandler : ICommandHandler +{ + /// + public async Task> Handle( + CreateLongToStringCommand request, + CancellationToken cancellationToken) + { + return CommandResponse.Success(new LongToStringModel() { Id = request.Id }); + } +} diff --git a/test/Cnblogs.Architecture.IntegrationTestProject/Application/Queries/GetLongToStringQuery.cs b/test/Cnblogs.Architecture.IntegrationTestProject/Application/Queries/GetLongToStringQuery.cs new file mode 100644 index 0000000..ac2ac59 --- /dev/null +++ b/test/Cnblogs.Architecture.IntegrationTestProject/Application/Queries/GetLongToStringQuery.cs @@ -0,0 +1,6 @@ +using Cnblogs.Architecture.Ddd.Cqrs.Abstractions; +using Cnblogs.Architecture.IntegrationTestProject.Models; + +namespace Cnblogs.Architecture.IntegrationTestProject.Application.Queries; + +public record GetLongToStringQuery(long Id) : IQuery; diff --git a/test/Cnblogs.Architecture.IntegrationTestProject/Application/Queries/GetLongToStringQueryHandler.cs b/test/Cnblogs.Architecture.IntegrationTestProject/Application/Queries/GetLongToStringQueryHandler.cs new file mode 100644 index 0000000..7e67258 --- /dev/null +++ b/test/Cnblogs.Architecture.IntegrationTestProject/Application/Queries/GetLongToStringQueryHandler.cs @@ -0,0 +1,13 @@ +using Cnblogs.Architecture.Ddd.Cqrs.Abstractions; +using Cnblogs.Architecture.IntegrationTestProject.Models; + +namespace Cnblogs.Architecture.IntegrationTestProject.Application.Queries; + +public class GetLongToStringQueryHandler : IQueryHandler +{ + /// + public async Task Handle(GetLongToStringQuery request, CancellationToken cancellationToken) + { + return new LongToStringModel() { Id = request.Id }; + } +} diff --git a/test/Cnblogs.Architecture.IntegrationTestProject/Controllers/TestController.cs b/test/Cnblogs.Architecture.IntegrationTestProject/Controllers/TestController.cs index 9207d1f..621e2e5 100644 --- a/test/Cnblogs.Architecture.IntegrationTestProject/Controllers/TestController.cs +++ b/test/Cnblogs.Architecture.IntegrationTestProject/Controllers/TestController.cs @@ -2,6 +2,8 @@ using Cnblogs.Architecture.Ddd.Cqrs.AspNetCore; using Cnblogs.Architecture.Ddd.Infrastructure.Abstractions; using Cnblogs.Architecture.IntegrationTestProject.Application.Commands; +using Cnblogs.Architecture.IntegrationTestProject.Application.Queries; +using Cnblogs.Architecture.IntegrationTestProject.Models; using Cnblogs.Architecture.IntegrationTestProject.Payloads; using MediatR; using Microsoft.AspNetCore.Mvc; @@ -10,15 +12,8 @@ namespace Cnblogs.Architecture.IntegrationTestProject.Controllers; [ApiVersion("1")] [Route("/api/v{version:apiVersion}/mvc")] -public class TestController : ApiControllerBase +public class TestController(IMediator mediator) : ApiControllerBase { - private readonly IMediator _mediator; - - public TestController(IMediator mediator) - { - _mediator = mediator; - } - [HttpGet("paging")] public Task PagingParamsAsync([FromQuery] PagingParams? pagingParams) { @@ -29,7 +24,20 @@ public TestController(IMediator mediator) public async Task PutStringAsync(int id, [FromBody] UpdatePayload payload) { var response = - await _mediator.Send(new UpdateCommand(id, payload.NeedValidationError, payload.NeedExecutionError)); + await mediator.Send(new UpdateCommand(id, payload.NeedValidationError, payload.NeedExecutionError)); + return HandleCommandResponse(response); + } + + [HttpGet("json/long-to-string/{id:long}")] + public async Task GetLongToStringModelAsync(long id) + { + return await mediator.Send(new GetLongToStringQuery(id)); + } + + [HttpPost("json/long-to-string")] + public async Task CreateLongToStringModelAsync([FromBody] LongToStringModel model) + { + var response = await mediator.Send(new CreateLongToStringCommand(model.Id)); return HandleCommandResponse(response); } } diff --git a/test/Cnblogs.Architecture.IntegrationTestProject/Models/LongToStringModel.cs b/test/Cnblogs.Architecture.IntegrationTestProject/Models/LongToStringModel.cs new file mode 100644 index 0000000..7b543b5 --- /dev/null +++ b/test/Cnblogs.Architecture.IntegrationTestProject/Models/LongToStringModel.cs @@ -0,0 +1,6 @@ +namespace Cnblogs.Architecture.IntegrationTestProject.Models; + +public class LongToStringModel +{ + public long Id { get; set; } +} diff --git a/test/Cnblogs.Architecture.IntegrationTestProject/Program.cs b/test/Cnblogs.Architecture.IntegrationTestProject/Program.cs index 6c9aa95..99d76c1 100644 --- a/test/Cnblogs.Architecture.IntegrationTestProject/Program.cs +++ b/test/Cnblogs.Architecture.IntegrationTestProject/Program.cs @@ -12,9 +12,10 @@ var builder = WebApplication.CreateBuilder(args); builder.Services.AddCqrs(Assembly.GetExecutingAssembly(), typeof(TestIntegrationEvent).Assembly) + .UseLongToStringJsonConverter() .AddDefaultDateTimeAndRandomProvider() .AddEventBus(o => o.UseDapr(Constants.AppName)); -builder.Services.AddControllers().AddCqrsModelBinderProvider(); +builder.Services.AddControllers().AddCqrsModelBinderProvider().AddLongToStringJsonConverter(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddCnblogsApiVersioning(); @@ -46,6 +47,8 @@ async (int stringId, [FromQuery] bool found = true) => await Task.FromResult(new GetStringQuery(StringId: stringId, Found: found))); v1.MapQuery("strings"); +v1.MapQuery("long-to-string/{id:long}"); +v1.MapCommand("long-to-string"); v1.MapCommand( "strings", (CreatePayload payload) => Task.FromResult(new CreateCommand(payload.NeedError, payload.Data))); diff --git a/test/Cnblogs.Architecture.IntegrationTests/CustomJsonConverterTests.cs b/test/Cnblogs.Architecture.IntegrationTests/CustomJsonConverterTests.cs new file mode 100644 index 0000000..dd7aa41 --- /dev/null +++ b/test/Cnblogs.Architecture.IntegrationTests/CustomJsonConverterTests.cs @@ -0,0 +1,96 @@ +using System.Net.Http.Json; +using System.Text; +using System.Text.Json; +using Cnblogs.Architecture.IntegrationTestProject; +using Cnblogs.Architecture.IntegrationTestProject.Models; +using FluentAssertions; +using Microsoft.AspNetCore.Mvc.Testing; + +namespace Cnblogs.Architecture.IntegrationTests; + +public class CustomJsonConverterTests +{ + private static readonly JsonSerializerOptions WebDefaults = new(JsonSerializerDefaults.Web); + + [Theory] + [InlineData("/api/v1/mvc/json/long-to-string/")] + [InlineData("/api/v1/long-to-string/")] + public async Task LongToJson_WriteLongToString_CanBeParsedByServerAsync(string baseUrl) + { + // Arrange + const long id = 202410267558024668; + var builder = new WebApplicationFactory(); + + // Act + var response = await builder.CreateClient().GetAsync(baseUrl + id); + var serverObject = await response.Content.ReadFromJsonAsync(WebDefaults); + + // Assert + serverObject.Should().BeEquivalentTo(new LongToStringModel() { Id = id }); + } + + [Theory] + [InlineData("/api/v1/mvc/json/long-to-string/")] + [InlineData("/api/v1/long-to-string/")] + public async Task LongToJson_WriteLongToString_IsStringInJsonAsync(string baseUrl) + { + // Arrange + const long id = 202410267558024668; + var builder = new WebApplicationFactory(); + + // Act + var response = await builder.CreateClient().GetAsync(baseUrl + id); + var browserObject = await response.Content.ReadFromJsonAsync(WebDefaults); + + // Assert + browserObject.EnumerateObject().First().Value.GetString().Should().Be(id.ToString()); + } + + [Theory] + [InlineData("/api/v1/mvc/json/long-to-string/")] + [InlineData("/api/v1/long-to-string/")] + public async Task LongToJson_ReadLongFromString_SuccessAsync(string url) + { + // Arrange + const string json = """ + { + "id": "202410267558024668" + } + """; + + var builder = new WebApplicationFactory(); + + // Act + var response = await builder.CreateClient().PostAsync( + url, + new StringContent(json, Encoding.UTF8, "application/json")); + var model = await response.Content.ReadFromJsonAsync(WebDefaults); + + // Assert + model.EnumerateObject().First().Value.GetString().Should().Be("202410267558024668"); + } + + [Theory] + [InlineData("/api/v1/mvc/json/long-to-string/")] + [InlineData("/api/v1/long-to-string/")] + public async Task LongToJson_ReadLongFromNumber_SuccessAsync(string url) + { + // Arrange + const string json = """ + { + "id": 202410267558024668 + } + """; + + var builder = new WebApplicationFactory(); + + // Act + var response = await builder.CreateClient().PostAsync( + url, + new StringContent(json, Encoding.UTF8, "application/json")); + var model = await response.Content.ReadFromJsonAsync(WebDefaults); + + // Assert + model.EnumerateObject().First().Value.GetString().Should().Be("202410267558024668"); + } +} From a2db73fe3d17a6ba58ada6136bbf56df478d98f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B2=88=E6=98=9F=E7=B9=81?= Date: Sun, 27 Oct 2024 15:11:08 +0800 Subject: [PATCH 2/3] chore: code clean up --- .../Application/Commands/CreateLongToStringCommandHandler.cs | 4 ++-- .../Application/Queries/GetLongToStringQueryHandler.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/Cnblogs.Architecture.IntegrationTestProject/Application/Commands/CreateLongToStringCommandHandler.cs b/test/Cnblogs.Architecture.IntegrationTestProject/Application/Commands/CreateLongToStringCommandHandler.cs index 830007b..10a1b3d 100644 --- a/test/Cnblogs.Architecture.IntegrationTestProject/Application/Commands/CreateLongToStringCommandHandler.cs +++ b/test/Cnblogs.Architecture.IntegrationTestProject/Application/Commands/CreateLongToStringCommandHandler.cs @@ -7,10 +7,10 @@ namespace Cnblogs.Architecture.IntegrationTestProject.Application.Commands; public class CreateLongToStringCommandHandler : ICommandHandler { /// - public async Task> Handle( + public Task> Handle( CreateLongToStringCommand request, CancellationToken cancellationToken) { - return CommandResponse.Success(new LongToStringModel() { Id = request.Id }); + return Task.FromResult(CommandResponse.Success(new LongToStringModel() { Id = request.Id })); } } diff --git a/test/Cnblogs.Architecture.IntegrationTestProject/Application/Queries/GetLongToStringQueryHandler.cs b/test/Cnblogs.Architecture.IntegrationTestProject/Application/Queries/GetLongToStringQueryHandler.cs index 7e67258..3583d8e 100644 --- a/test/Cnblogs.Architecture.IntegrationTestProject/Application/Queries/GetLongToStringQueryHandler.cs +++ b/test/Cnblogs.Architecture.IntegrationTestProject/Application/Queries/GetLongToStringQueryHandler.cs @@ -6,8 +6,8 @@ namespace Cnblogs.Architecture.IntegrationTestProject.Application.Queries; public class GetLongToStringQueryHandler : IQueryHandler { /// - public async Task Handle(GetLongToStringQuery request, CancellationToken cancellationToken) + public Task Handle(GetLongToStringQuery request, CancellationToken cancellationToken) { - return new LongToStringModel() { Id = request.Id }; + return Task.FromResult((LongToStringModel?)new LongToStringModel() { Id = request.Id }); } } From 3d8c80d465de6ff2ec5f32ca4e45fdf992f05e94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B2=88=E6=98=9F=E7=B9=81?= Date: Sun, 27 Oct 2024 15:36:41 +0800 Subject: [PATCH 3/3] refactor: rename extension method --- .../CqrsHttpOptionsInjector.cs | 2 +- test/Cnblogs.Architecture.IntegrationTestProject/Program.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CqrsHttpOptionsInjector.cs b/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CqrsHttpOptionsInjector.cs index 76b0246..8de27bc 100644 --- a/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CqrsHttpOptionsInjector.cs +++ b/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CqrsHttpOptionsInjector.cs @@ -48,7 +48,7 @@ public static CqrsInjector UseCustomCommandErrorResponseMapper( /// /// /// - public static CqrsInjector UseLongToStringJsonConverter(this CqrsInjector injector) + public static CqrsInjector AddLongToStringJsonConverter(this CqrsInjector injector) { injector.Services.Configure( o => o.DefaultJsonSerializerOptions.Converters.Add(new LongToStringConverter())); diff --git a/test/Cnblogs.Architecture.IntegrationTestProject/Program.cs b/test/Cnblogs.Architecture.IntegrationTestProject/Program.cs index 99d76c1..45aef48 100644 --- a/test/Cnblogs.Architecture.IntegrationTestProject/Program.cs +++ b/test/Cnblogs.Architecture.IntegrationTestProject/Program.cs @@ -12,7 +12,7 @@ var builder = WebApplication.CreateBuilder(args); builder.Services.AddCqrs(Assembly.GetExecutingAssembly(), typeof(TestIntegrationEvent).Assembly) - .UseLongToStringJsonConverter() + .AddLongToStringJsonConverter() .AddDefaultDateTimeAndRandomProvider() .AddEventBus(o => o.UseDapr(Constants.AppName)); builder.Services.AddControllers().AddCqrsModelBinderProvider().AddLongToStringJsonConverter();