diff --git a/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/ApiControllerBase.cs b/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/ApiControllerBase.cs index ef6dbcf..0afa868 100644 --- a/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/ApiControllerBase.cs +++ b/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/ApiControllerBase.cs @@ -1,21 +1,20 @@ using Cnblogs.Architecture.Ddd.Cqrs.Abstractions; using Cnblogs.Architecture.Ddd.Domain.Abstractions; - using Microsoft.AspNetCore.Mvc; namespace Cnblogs.Architecture.Ddd.Cqrs.AspNetCore; /// -/// Controller 基类,提供自动处理 的方法。 +/// A base class for an API controller with methods that return based ons . /// [ApiController] public class ApiControllerBase : ControllerBase { /// - /// 处理 CommandResponse 并返回对应的状态码,成功-204,错误-400。 + /// Handle command response and return 204 if success, 400 if error. /// - /// 任务结果。 - /// 错误类型。 + /// The command response. + /// The type of error. /// protected IActionResult HandleCommandResponse(CommandResponse response) where TError : Enumeration @@ -29,11 +28,11 @@ protected IActionResult HandleCommandResponse(CommandResponse re } /// - /// 自动处理命令返回的结果,成功-200,失败-400。 + /// Handle command response and return 204 if success, 400 if error. /// - /// 命令执行结果。 - /// 返回类型。 - /// 错误类型。 + /// The command response. + /// The response type when success. + /// The error type. /// protected IActionResult HandleCommandResponse(CommandResponse response) where TError : Enumeration @@ -54,11 +53,11 @@ private IActionResult HandleErrorCommandResponse(CommandResponse return BadRequest(response.ValidationError!.Message); } - if (response.IsConcurrentError && response.LockAcquired == false) + if (response is { IsConcurrentError: true, LockAcquired: false }) { return StatusCode(429); } return BadRequest(response.ErrorCode?.Name ?? response.ErrorMessage); } -} \ No newline at end of file +} diff --git a/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/ApiVersioningInjectors.cs b/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/ApiVersioningInjectors.cs index 0f13869..4213b10 100644 --- a/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/ApiVersioningInjectors.cs +++ b/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/ApiVersioningInjectors.cs @@ -5,12 +5,12 @@ namespace Microsoft.Extensions.DependencyInjection; /// -/// Api Versioning 注入扩展 +/// Extension methods to inject api versioning. /// public static class ApiVersioningInjectors { /// - /// 添加 API Versioning,默认使用 + /// Add API Versioning, use by default. /// /// /// @@ -26,4 +26,4 @@ public static IApiVersioningBuilder AddCnblogsApiVersioning(this IServiceCollect o.SubstituteApiVersionInUrl = true; }); } -} \ No newline at end of file +} diff --git a/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CommandEndpointHandler.cs b/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CommandEndpointHandler.cs index 38f15cc..7e510b7 100644 --- a/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CommandEndpointHandler.cs +++ b/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CommandEndpointHandler.cs @@ -1,20 +1,18 @@ using Cnblogs.Architecture.Ddd.Cqrs.Abstractions; - using MediatR; - using Microsoft.AspNetCore.Http; namespace Cnblogs.Architecture.Ddd.Cqrs.AspNetCore; /// -/// 命令执行器,自动将返回内容提交给 mediator 并返回结果。 +/// Execute command returned by endpoint handler, and then map command response to HTTP response. /// public class CommandEndpointHandler : IEndpointFilter { private readonly IMediator _mediator; /// - /// 构造一个命令执行器。 + /// Create a command endpoint handler. /// /// public CommandEndpointHandler(IMediator mediator) @@ -73,4 +71,4 @@ private static IResult HandleErrorCommandResponse(CommandResponse response) return Results.BadRequest(response.GetErrorMessage()); } -} \ No newline at end of file +} diff --git a/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/ControllerOptionInjector.cs b/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/ControllerOptionInjector.cs index 39fa946..b8c8d1a 100644 --- a/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/ControllerOptionInjector.cs +++ b/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/ControllerOptionInjector.cs @@ -1,16 +1,17 @@ using Cnblogs.Architecture.Ddd.Cqrs.AspNetCore; +using Cnblogs.Architecture.Ddd.Infrastructure.Abstractions; using Microsoft.AspNetCore.Mvc; // ReSharper disable once CheckNamespace namespace Microsoft.Extensions.DependencyInjection; /// -/// 用于注入 Model Binder 的扩展方法。 +/// Extensions to inject custom model binder for CQRS. /// public static class ControllerOptionInjector { /// - /// 添加 CQRS 相关的 Model Binder Provider + /// Add custom model binder used for CQRS, like model binder for . /// /// public static void AddCqrsModelBinderProvider(this MvcOptions options) @@ -19,11 +20,11 @@ public static void AddCqrsModelBinderProvider(this MvcOptions options) } /// - /// 添加 CQRS 相关的 Model Binder Provider + /// Add custom model binder used for CQRS, like model binder for . /// /// public static void AddCqrsModelBinderProvider(this IMvcBuilder builder) { builder.AddMvcOptions(options => options.AddCqrsModelBinderProvider()); } -} \ No newline at end of file +} diff --git a/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CqrsModelBinderProvider.cs b/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CqrsModelBinderProvider.cs index 1cbf86b..b5816a8 100644 --- a/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CqrsModelBinderProvider.cs +++ b/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CqrsModelBinderProvider.cs @@ -6,7 +6,7 @@ namespace Cnblogs.Architecture.Ddd.Cqrs.AspNetCore; /// -/// Model Binder Provider for custom types +/// Model Binder Provider for custom types used in CQRS. /// public class CqrsModelBinderProvider : IModelBinderProvider { @@ -20,4 +20,4 @@ public class CqrsModelBinderProvider : IModelBinderProvider return null; } -} \ No newline at end of file +} diff --git a/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CqrsRouteMapper.cs b/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CqrsRouteMapper.cs index 395c73d..a23fa1b 100644 --- a/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CqrsRouteMapper.cs +++ b/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CqrsRouteMapper.cs @@ -9,7 +9,7 @@ namespace Cnblogs.Architecture.Ddd.Cqrs.AspNetCore; /// -/// 用于 Minimum API CQRS 路径注册的扩展方法。 +/// Extension methods used for register Command and Query endpoint in minimal API. /// public static class CqrsRouteMapper { @@ -18,11 +18,11 @@ public static class CqrsRouteMapper private static readonly List CommandTypes = new() { typeof(ICommand<>), typeof(ICommand<,>) }; /// - /// 添加查询 API,使用 GET 方法访问,参数将自动从路径或查询字符串获取。 + /// Map a query API, using GET method. would been constructed from route and query string. /// /// - /// 路径模板。 - /// 查询类型。 + /// The route template for API. + /// The type of the query. /// public static IEndpointConventionBuilder MapQuery( this IEndpointRouteBuilder app, @@ -32,11 +32,11 @@ public static IEndpointConventionBuilder MapQuery( } /// - /// 添加一个命令 API,根据前缀选择 HTTP Method,错误会被自动处理。 + /// Map a command API, using different HTTP methods based on prefix. See example for details. /// /// - /// 路径模板。 - /// 命令类型。 + /// The route template. + /// The type of the command. /// /// /// app.MapCommand<CreateItemCommand>("/items"); // Starts with 'Create' or 'Add' - POST @@ -54,36 +54,11 @@ public static IEndpointConventionBuilder MapCommand( } /// - /// 添加一个命令 API,根据前缀选择 HTTP Method,错误会被自动处理。 + /// Map a query API, using GET method. /// /// - /// 路径模板。 - /// 返回 的委托。 - /// 命令类型。 - /// - /// - /// app.MapCommand<CreateItemCommand>("/items"); // Starts with 'Create' or 'Add' - POST - /// app.MapCommand<UpdateItemCommand>("/items/{id:int}") // Starts with 'Update' or 'Replace' - PUT - /// app.MapCommand<DeleteCommand>("/items/{id:int}") // Starts with 'Delete' or 'Remove' - DELETE - /// app.MapCommand<ResetItemCommand>("/items/{id:int}:reset) // Others - PUT - /// - /// - /// - // ReSharper disable once UnusedTypeParameter - public static IEndpointConventionBuilder MapCommand( - this IEndpointRouteBuilder app, - [StringSyntax("Route")] string route, - Delegate handler) - { - return app.MapCommand(route, handler); - } - - /// - /// 添加一个查询 API,使用 GET 方法访问。 - /// - /// - /// 路径模板。 - /// 构造查询的方法,需要返回 的对象。 + /// The route template. + /// The delegate that returns a instance. /// public static IEndpointConventionBuilder MapQuery( this IEndpointRouteBuilder app, @@ -102,11 +77,11 @@ public static IEndpointConventionBuilder MapQuery( } /// - /// 添加一个命令 API,根据前缀选择 HTTP Method,错误会被自动处理。 + /// Map a command API, using different method based on type name prefix. /// /// - /// 路径模板。 - /// 构造命令的方法,需要返回 类型的对象。 + /// The route template. + /// The delegate that returns a instance of . /// /// /// @@ -142,11 +117,11 @@ public static IEndpointConventionBuilder MapCommand( } /// - /// 添加一个命令 API,使用 POST 方法访问,错误会被自动处理。 + /// Map a command API, using POST method. /// /// - /// 路径模板。 - /// 构造命令的方法,需要返回 类型的对象。 + /// The route template. + /// The delegate that returns a instance of . /// public static IEndpointConventionBuilder MapPostCommand( this IEndpointRouteBuilder app, @@ -158,11 +133,11 @@ public static IEndpointConventionBuilder MapPostCommand( } /// - /// 添加一个命令 API,使用 PUT 方法访问,错误会被自动处理。 + /// Map a command API, using PUT method. /// /// - /// 路径模板。 - /// 构造命令的方法,需要返回 类型的对象。 + /// The route template. + /// The delegate that returns a instance of . /// public static IEndpointConventionBuilder MapPutCommand( this IEndpointRouteBuilder app, @@ -174,11 +149,11 @@ public static IEndpointConventionBuilder MapPutCommand( } /// - /// 添加一个命令 API,使用 DELETE 方法访问,错误会被自动处理。 + /// Map a command API, using DELETE method. /// /// - /// 路径模板。 - /// 构造命令的方法,需要返回 类型的对象。 + /// The route template. + /// The delegate that returns a instance of . /// public static IEndpointConventionBuilder MapDeleteCommand( this IEndpointRouteBuilder app, @@ -199,4 +174,4 @@ private static void EnsureDelegateReturnTypeIsCommand(Delegate handler) "handler does not return command, check if delegate returns type that implements ICommand<> or ICommand<,>"); } } -} \ No newline at end of file +} diff --git a/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/PagingParamsModelBinder.cs b/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/PagingParamsModelBinder.cs index 665f165..df11d82 100644 --- a/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/PagingParamsModelBinder.cs +++ b/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/PagingParamsModelBinder.cs @@ -5,7 +5,7 @@ namespace Cnblogs.Architecture.Ddd.Cqrs.AspNetCore; /// -/// Model Binder for +/// Model Binder for /// public class PagingParamsModelBinder : IModelBinder { @@ -48,4 +48,4 @@ public Task BindModelAsync(ModelBindingContext bindingContext) bindingContext.Result = ModelBindingResult.Success(pagingParams); return Task.CompletedTask; } -} \ No newline at end of file +} diff --git a/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/QueryEndpointHandler.cs b/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/QueryEndpointHandler.cs index 1834998..5782fda 100644 --- a/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/QueryEndpointHandler.cs +++ b/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/QueryEndpointHandler.cs @@ -5,16 +5,16 @@ namespace Cnblogs.Architecture.Ddd.Cqrs.AspNetCore; /// -/// 查询执行器,自动将返回内容提交给 mediator 并返回结果。 +/// The query executor, auto send query to . /// public class QueryEndpointHandler : IEndpointFilter { private readonly IMediator _mediator; /// - /// 创建一个查询执行器。 + /// Create a . /// - /// + /// The mediator to use. public QueryEndpointHandler(IMediator mediator) { _mediator = mediator; @@ -32,4 +32,4 @@ public QueryEndpointHandler(IMediator mediator) var response = await _mediator.Send(query); return response; } -} \ No newline at end of file +} diff --git a/test/Cnblogs.Architecture.IntegrationTestProject/Program.cs b/test/Cnblogs.Architecture.IntegrationTestProject/Program.cs index 240ded6..766731b 100644 --- a/test/Cnblogs.Architecture.IntegrationTestProject/Program.cs +++ b/test/Cnblogs.Architecture.IntegrationTestProject/Program.cs @@ -37,8 +37,8 @@ var v1 = apis.MapGroup("/api/v{version:apiVersion}").HasApiVersion(1); v1.MapQuery("strings/{id:int}"); v1.MapQuery("strings"); -v1.MapCommand("strings", (CreatePayload payload) => new CreateCommand(payload.NeedError)); -v1.MapCommand( +v1.MapCommand("strings", (CreatePayload payload) => new CreateCommand(payload.NeedError)); +v1.MapCommand( "strings/{id:int}", (int id, UpdatePayload payload) => new UpdateCommand(id, payload.NeedError)); v1.MapCommand("strings/{id:int}"); @@ -51,4 +51,4 @@ namespace Cnblogs.Architecture.IntegrationTestProject public partial class Program { } -} \ No newline at end of file +}