From dbfb59f461959a8ff6452b895396549dcdcdcc99 Mon Sep 17 00:00:00 2001 From: hello Date: Thu, 12 Sep 2024 22:01:35 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=86=E5=B8=83=E5=BC=8F=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E7=9A=84=E8=AE=BE=E8=AE=A1=E4=B8=8E=E6=8A=BD=E8=B1=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Behaviors/TransactionBehavior.cs | 5 +- .../Controllers/OrdersController.cs | 2 - .../Services/MessageService.cs | 2 - .../Abstractions/DistributedEvent.cs | 24 ++++++++ .../DistributedEventBusBuilderExtensions.cs | 61 +++++++++++++++++++ .../DistributedEventBusOptions.cs | 20 ++++++ .../Abstractions/IDistributedEventBus.cs | 10 +++ .../IDistributedEventBusBuilder.cs | 12 ++++ .../Abstractions/IDistributedEventHandler.cs | 17 ++++++ 9 files changed, 148 insertions(+), 5 deletions(-) create mode 100644 src/HelloShop.ServiceDefaults/DistributedEvents/Abstractions/DistributedEvent.cs create mode 100644 src/HelloShop.ServiceDefaults/DistributedEvents/Abstractions/DistributedEventBusBuilderExtensions.cs create mode 100644 src/HelloShop.ServiceDefaults/DistributedEvents/Abstractions/DistributedEventBusOptions.cs create mode 100644 src/HelloShop.ServiceDefaults/DistributedEvents/Abstractions/IDistributedEventBus.cs create mode 100644 src/HelloShop.ServiceDefaults/DistributedEvents/Abstractions/IDistributedEventBusBuilder.cs create mode 100644 src/HelloShop.ServiceDefaults/DistributedEvents/Abstractions/IDistributedEventHandler.cs diff --git a/src/HelloShop.OrderingService/Behaviors/TransactionBehavior.cs b/src/HelloShop.OrderingService/Behaviors/TransactionBehavior.cs index 14ff297..fda8b7e 100644 --- a/src/HelloShop.OrderingService/Behaviors/TransactionBehavior.cs +++ b/src/HelloShop.OrderingService/Behaviors/TransactionBehavior.cs @@ -1,4 +1,7 @@ -using HelloShop.OrderingService.Extensions; +// Copyright (c) HelloShop Corporation. All rights reserved. +// See the license file in the project root for more information. + +using HelloShop.OrderingService.Extensions; using HelloShop.OrderingService.Infrastructure; using MediatR; using Microsoft.EntityFrameworkCore; diff --git a/src/HelloShop.OrderingService/Controllers/OrdersController.cs b/src/HelloShop.OrderingService/Controllers/OrdersController.cs index 87104f4..bc40e14 100644 --- a/src/HelloShop.OrderingService/Controllers/OrdersController.cs +++ b/src/HelloShop.OrderingService/Controllers/OrdersController.cs @@ -7,10 +7,8 @@ using HelloShop.OrderingService.Commands.Orders; using HelloShop.OrderingService.Models.Orders; using MediatR; using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Components.Forms; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.ModelBinding; -using System.ComponentModel.DataAnnotations; using System.Security.Claims; namespace HelloShop.OrderingService.Controllers; diff --git a/src/HelloShop.OrderingService/Services/MessageService.cs b/src/HelloShop.OrderingService/Services/MessageService.cs index e8e43fa..8e61695 100644 --- a/src/HelloShop.OrderingService/Services/MessageService.cs +++ b/src/HelloShop.OrderingService/Services/MessageService.cs @@ -1,8 +1,6 @@ // Copyright (c) HelloShop Corporation. All rights reserved. // See the license file in the project root for more information. -using Microsoft.Extensions.Logging; - namespace HelloShop.OrderingService.Services { public class MessageService(ILogger logger) : IEmailSender, ISmsSender diff --git a/src/HelloShop.ServiceDefaults/DistributedEvents/Abstractions/DistributedEvent.cs b/src/HelloShop.ServiceDefaults/DistributedEvents/Abstractions/DistributedEvent.cs new file mode 100644 index 0000000..167cf0d --- /dev/null +++ b/src/HelloShop.ServiceDefaults/DistributedEvents/Abstractions/DistributedEvent.cs @@ -0,0 +1,24 @@ +// Copyright (c) HelloShop Corporation. All rights reserved. +// See the license file in the project root for more information. + +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace HelloShop.ServiceDefaults.DistributedEvents.Abstractions +{ + public record DistributedEvent + { + public DistributedEvent() + { + Id = Guid.NewGuid(); + CreationTime = DateTimeOffset.UtcNow; + } + + public Guid Id { get; set; } + + public DateTimeOffset CreationTime { get; set; } + + [JsonExtensionData] + public Dictionary? ExtensionData { get; set; } + } +} diff --git a/src/HelloShop.ServiceDefaults/DistributedEvents/Abstractions/DistributedEventBusBuilderExtensions.cs b/src/HelloShop.ServiceDefaults/DistributedEvents/Abstractions/DistributedEventBusBuilderExtensions.cs new file mode 100644 index 0000000..e323725 --- /dev/null +++ b/src/HelloShop.ServiceDefaults/DistributedEvents/Abstractions/DistributedEventBusBuilderExtensions.cs @@ -0,0 +1,61 @@ +// Copyright (c) HelloShop Corporation. All rights reserved. +// See the license file in the project root for more information. + +using Microsoft.Extensions.DependencyInjection; +using System.Reflection; +using System.Text.Json; + +namespace HelloShop.ServiceDefaults.DistributedEvents.Abstractions +{ + public static class DistributedEventBusBuilderExtensions + { + public static IDistributedEventBusBuilder ConfigureJsonOptions(this IDistributedEventBusBuilder eventBusBuilder, Action configure) + { + eventBusBuilder.Services.Configure(o => + { + configure(o.JsonSerializerOptions); + }); + + return eventBusBuilder; + } + + public static IDistributedEventBusBuilder AddSubscription(this IDistributedEventBusBuilder eventBusBuilder) where TEvent : DistributedEvent where TEventHandler : class, IDistributedEventHandler + { + eventBusBuilder.Services.AddKeyedTransient(typeof(TEvent)); + + eventBusBuilder.Services.Configure(o => + { + o.EventTypes[typeof(TEvent).Name] = typeof(TEvent); + }); + + return eventBusBuilder; + } + + public static IDistributedEventBusBuilder AddSubscription(this IDistributedEventBusBuilder eventBusBuilder, Type eventType, Type eventHandlerType) + { + eventBusBuilder.Services.AddKeyedTransient(typeof(IDistributedEventHandler), eventType, eventHandlerType); + + eventBusBuilder.Services.Configure(o => + { + o.EventTypes[eventType.Name] = eventType; + }); + + return eventBusBuilder; + } + + public static IDistributedEventBusBuilder AddSubscriptionFromAssembly(this IDistributedEventBusBuilder eventBusBuilder, Assembly? assembly = null) + { + assembly ??= Assembly.GetCallingAssembly(); + + var handlers = assembly.GetTypes().Where(t => t.IsAssignableTo(typeof(IDistributedEventHandler))).ToList(); + + handlers.ForEach(handler => + { + var eventType = handler.GetInterfaces().Single(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IDistributedEventHandler<>)).GetGenericArguments().Single(); + eventBusBuilder.AddSubscription(eventType, handler); + }); + + return eventBusBuilder; + } + } +} diff --git a/src/HelloShop.ServiceDefaults/DistributedEvents/Abstractions/DistributedEventBusOptions.cs b/src/HelloShop.ServiceDefaults/DistributedEvents/Abstractions/DistributedEventBusOptions.cs new file mode 100644 index 0000000..d45915a --- /dev/null +++ b/src/HelloShop.ServiceDefaults/DistributedEvents/Abstractions/DistributedEventBusOptions.cs @@ -0,0 +1,20 @@ +// Copyright (c) HelloShop Corporation. All rights reserved. +// See the license file in the project root for more information. + +using System.Text.Json; +using System.Text.Json.Serialization.Metadata; + +namespace HelloShop.ServiceDefaults.DistributedEvents.Abstractions +{ + public class DistributedEventBusOptions + { + public Dictionary EventTypes { get; } = []; + + public JsonSerializerOptions JsonSerializerOptions { get; } = new(DefaultSerializerOptions); + + internal static readonly JsonSerializerOptions DefaultSerializerOptions = new() + { + TypeInfoResolver = JsonSerializer.IsReflectionEnabledByDefault ? new DefaultJsonTypeInfoResolver() : JsonTypeInfoResolver.Combine() + }; + } +} diff --git a/src/HelloShop.ServiceDefaults/DistributedEvents/Abstractions/IDistributedEventBus.cs b/src/HelloShop.ServiceDefaults/DistributedEvents/Abstractions/IDistributedEventBus.cs new file mode 100644 index 0000000..13b1653 --- /dev/null +++ b/src/HelloShop.ServiceDefaults/DistributedEvents/Abstractions/IDistributedEventBus.cs @@ -0,0 +1,10 @@ +// Copyright (c) HelloShop Corporation. All rights reserved. +// See the license file in the project root for more information. + +namespace HelloShop.ServiceDefaults.DistributedEvents.Abstractions +{ + public interface IDistributedEventBus + { + Task PublishAsync(DistributedEvent @event, CancellationToken cancellationToken = default); + } +} diff --git a/src/HelloShop.ServiceDefaults/DistributedEvents/Abstractions/IDistributedEventBusBuilder.cs b/src/HelloShop.ServiceDefaults/DistributedEvents/Abstractions/IDistributedEventBusBuilder.cs new file mode 100644 index 0000000..66e3de5 --- /dev/null +++ b/src/HelloShop.ServiceDefaults/DistributedEvents/Abstractions/IDistributedEventBusBuilder.cs @@ -0,0 +1,12 @@ +// Copyright (c) HelloShop Corporation. All rights reserved. +// See the license file in the project root for more information. + +using Microsoft.Extensions.DependencyInjection; + +namespace HelloShop.ServiceDefaults.DistributedEvents.Abstractions +{ + public interface IDistributedEventBusBuilder + { + public IServiceCollection Services { get; } + } +} diff --git a/src/HelloShop.ServiceDefaults/DistributedEvents/Abstractions/IDistributedEventHandler.cs b/src/HelloShop.ServiceDefaults/DistributedEvents/Abstractions/IDistributedEventHandler.cs new file mode 100644 index 0000000..f139764 --- /dev/null +++ b/src/HelloShop.ServiceDefaults/DistributedEvents/Abstractions/IDistributedEventHandler.cs @@ -0,0 +1,17 @@ +// Copyright (c) HelloShop Corporation. All rights reserved. +// See the license file in the project root for more information. + +namespace HelloShop.ServiceDefaults.DistributedEvents.Abstractions +{ + public interface IDistributedEventHandler + { + Task HandleAsync(DistributedEvent @event); + } + + public interface IDistributedEventHandler : IDistributedEventHandler where TDistributedEvent : DistributedEvent + { + Task HandleAsync(TDistributedEvent @event); + + Task IDistributedEventHandler.HandleAsync(DistributedEvent @event) => HandleAsync((TDistributedEvent)@event); + } +}