分布式事件的设计与抽象
This commit is contained in:
parent
fb424749c0
commit
dbfb59f461
@ -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 HelloShop.OrderingService.Infrastructure;
|
||||||
using MediatR;
|
using MediatR;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
@ -7,10 +7,8 @@ using HelloShop.OrderingService.Commands.Orders;
|
|||||||
using HelloShop.OrderingService.Models.Orders;
|
using HelloShop.OrderingService.Models.Orders;
|
||||||
using MediatR;
|
using MediatR;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Components.Forms;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
|
|
||||||
namespace HelloShop.OrderingService.Controllers;
|
namespace HelloShop.OrderingService.Controllers;
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) HelloShop Corporation. All rights reserved.
|
// Copyright (c) HelloShop Corporation. All rights reserved.
|
||||||
// See the license file in the project root for more information.
|
// See the license file in the project root for more information.
|
||||||
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
|
|
||||||
namespace HelloShop.OrderingService.Services
|
namespace HelloShop.OrderingService.Services
|
||||||
{
|
{
|
||||||
public class MessageService(ILogger<MessageService> logger) : IEmailSender, ISmsSender
|
public class MessageService(ILogger<MessageService> logger) : IEmailSender, ISmsSender
|
||||||
|
@ -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<string, JsonElement>? ExtensionData { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -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<JsonSerializerOptions> configure)
|
||||||
|
{
|
||||||
|
eventBusBuilder.Services.Configure<DistributedEventBusOptions>(o =>
|
||||||
|
{
|
||||||
|
configure(o.JsonSerializerOptions);
|
||||||
|
});
|
||||||
|
|
||||||
|
return eventBusBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IDistributedEventBusBuilder AddSubscription<TEvent, TEventHandler>(this IDistributedEventBusBuilder eventBusBuilder) where TEvent : DistributedEvent where TEventHandler : class, IDistributedEventHandler<TEvent>
|
||||||
|
{
|
||||||
|
eventBusBuilder.Services.AddKeyedTransient<IDistributedEventHandler, TEventHandler>(typeof(TEvent));
|
||||||
|
|
||||||
|
eventBusBuilder.Services.Configure<DistributedEventBusOptions>(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<DistributedEventBusOptions>(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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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<string, Type> EventTypes { get; } = [];
|
||||||
|
|
||||||
|
public JsonSerializerOptions JsonSerializerOptions { get; } = new(DefaultSerializerOptions);
|
||||||
|
|
||||||
|
internal static readonly JsonSerializerOptions DefaultSerializerOptions = new()
|
||||||
|
{
|
||||||
|
TypeInfoResolver = JsonSerializer.IsReflectionEnabledByDefault ? new DefaultJsonTypeInfoResolver() : JsonTypeInfoResolver.Combine()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -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; }
|
||||||
|
}
|
||||||
|
}
|
@ -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<in TDistributedEvent> : IDistributedEventHandler where TDistributedEvent : DistributedEvent
|
||||||
|
{
|
||||||
|
Task HandleAsync(TDistributedEvent @event);
|
||||||
|
|
||||||
|
Task IDistributedEventHandler.HandleAsync(DistributedEvent @event) => HandleAsync((TDistributedEvent)@event);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user