From 6af885a4f8b46179c6a8258c8ef2bf07acad4031 Mon Sep 17 00:00:00 2001 From: HiveBeats Date: Sun, 10 Mar 2024 18:20:41 +0700 Subject: [PATCH] fix: registration --- InServiceQue.Sample/DIExtensions.cs | 62 +++++++++++++++---- .../HostedServiceRegistrator.cs | 8 +-- InServiceQue.Sample/Program.cs | 7 ++- InServiceQue.Sample/SendMessageTask.cs | 4 +- InServiceQue/Services/QueueService.cs | 2 +- InServiceQue/Services/QueueTypeRegistry.cs | 3 +- 6 files changed, 63 insertions(+), 23 deletions(-) diff --git a/InServiceQue.Sample/DIExtensions.cs b/InServiceQue.Sample/DIExtensions.cs index b51bcbb..71a6bc6 100644 --- a/InServiceQue.Sample/DIExtensions.cs +++ b/InServiceQue.Sample/DIExtensions.cs @@ -7,11 +7,53 @@ using Microsoft.Extensions.DependencyInjection.Extensions; namespace InServiceQue.Sample; +public class InServiceQueBuilder +{ + private IServiceCollection _services; + private ITypeRegistry _typeRegistry; + private HostedServiceRegistrator _hostedServiceRegistrator; + public InServiceQueBuilder(IServiceCollection services) + { + _services = services; + StartBuilding(); + } + + private void StartBuilding() + { + _typeRegistry = new QueueTypeRegistry(); + _services.AddSingleton(_typeRegistry); + _hostedServiceRegistrator = new HostedServiceRegistrator(); + } + + public void AddQueue() + where T : IQueueTask + where THandler : IQueueHandler + { + _typeRegistry.RegisterTaskType(typeof(T).Name, typeof(THandler).GetInterfaces() + .First(x => x.IsGenericType + && x.GetGenericTypeDefinition() == typeof(IQueueHandler<>))); + + var taskType = typeof(T); + var queueHandlerType = typeof(THandler); + //can't resolve then + _services.AddScoped(typeof(IQueueHandler<>).MakeGenericType(taskType), queueHandlerType); + + var hostedServiceType = typeof(QueueService<>).MakeGenericType(taskType); + _hostedServiceRegistrator.RegisterHostedService(_services, hostedServiceType); + } +} + public static class DIExtensions { + public static void AddInServiceQue(this IServiceCollection services, Action buildAction) + + { + var builder = new InServiceQueBuilder(services); + buildAction(builder); + } + public static IServiceCollection RegisterInternals(this IServiceCollection services) { - services.AddSingleton(); services.AddTransient(); return services; } @@ -19,34 +61,30 @@ public static class DIExtensions public static IServiceCollection RegisterQueues(this IServiceCollection services) { using var sp = services.BuildServiceProvider(); + var queueHandlerType = typeof(IQueueHandler<>); // find all types in the assembly that implement IQueueHandler var queueTypes = Assembly.GetExecutingAssembly().GetTypes() .Where(t => t.IsClass && !t.IsAbstract && t.GetInterfaces() - .Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IQueueHandler<>))); + .Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == queueHandlerType)); var hostedServiceRegistrator = new HostedServiceRegistrator(); // register each query type with its corresponding interface foreach (var queueType in queueTypes) { // get the T from IQueueHandler - var type = queueType.GetInterfaces() - .Single(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IQueueHandler<>)); + var taskType = queueType.GetInterfaces() + .Single(i => i.IsGenericType && i.GetGenericTypeDefinition() == queueHandlerType); // register the query type as a scoped service with its corresponding interface services.AddScoped(queueType); var typeRegistry = sp.GetRequiredService(); - typeRegistry.RegisterTaskType(type.GenericTypeArguments.First().Name, type); + typeRegistry.RegisterTaskType(taskType.GenericTypeArguments.First().Name, taskType); - services.AddScoped(typeof(IQueueHandler<>) - .MakeGenericType(type.GenericTypeArguments), queueType); + services.AddScoped(queueType); - //todo: bug here - var hostedServiceType = typeof(QueueService<>).MakeGenericType(type.GenericTypeArguments); + var hostedServiceType = typeof(QueueService<>).MakeGenericType(taskType.GenericTypeArguments); hostedServiceRegistrator.RegisterHostedService(services, hostedServiceType); - - // services.AddSingleton(typeof(IQueueService<>) - // .MakeGenericType(type.GenericTypeArguments), ); } return services; diff --git a/InServiceQue.Sample/HostedServiceRegistrator.cs b/InServiceQue.Sample/HostedServiceRegistrator.cs index be8ee7a..0fac615 100644 --- a/InServiceQue.Sample/HostedServiceRegistrator.cs +++ b/InServiceQue.Sample/HostedServiceRegistrator.cs @@ -6,13 +6,13 @@ public class HostedServiceRegistrator { public void RegisterHostedService(IServiceCollection services, Type hostedServiceType) { - Type servicesType = typeof(HostedServiceRegistrator); - MethodInfo methodInfo = servicesType.GetMethod("AddHostedService"); - MethodInfo genericMethod = methodInfo.MakeGenericMethod(hostedServiceType); + var servicesType = typeof(HostedServiceRegistrator); + var methodInfo = servicesType.GetMethod(nameof(AddHostedService)); + var genericMethod = methodInfo.MakeGenericMethod(hostedServiceType); + genericMethod.Invoke(this, new object[] { services }); } - // Needed as a work-arround because we can't call the extension method with reflection. public IServiceCollection AddHostedService(IServiceCollection services) where THostedService : class, IHostedService => services.AddHostedService(); diff --git a/InServiceQue.Sample/Program.cs b/InServiceQue.Sample/Program.cs index 607fcb4..269609a 100644 --- a/InServiceQue.Sample/Program.cs +++ b/InServiceQue.Sample/Program.cs @@ -4,11 +4,12 @@ using InServiceQue.Sample; var builder = WebApplication.CreateBuilder(args); builder.Services.RegisterInternals(); -builder.Services.RegisterQueues(); +builder.Services.AddInServiceQue(builder => +{ + builder.AddQueue(); +}); var app = builder.Build(); - - app.MapGet("/", (string msg) => app.Services.GetService().Insert(new QueueTask(new SendMessageTask(new SendMessagePayload(){To = "John", From = "Garry", Message = msg})))); app.Run(); \ No newline at end of file diff --git a/InServiceQue.Sample/SendMessageTask.cs b/InServiceQue.Sample/SendMessageTask.cs index 1a9ff5d..e2a75db 100644 --- a/InServiceQue.Sample/SendMessageTask.cs +++ b/InServiceQue.Sample/SendMessageTask.cs @@ -20,12 +20,12 @@ public class SendMessageTask: IQueueTask { _payload = payload; } - + public string GetTypeString() { return nameof(SendMessageTask); } - + public string GetPayloadString() { return JsonSerializer.Serialize(_payload); diff --git a/InServiceQue/Services/QueueService.cs b/InServiceQue/Services/QueueService.cs index c866879..5a1761a 100644 --- a/InServiceQue/Services/QueueService.cs +++ b/InServiceQue/Services/QueueService.cs @@ -112,7 +112,7 @@ where T: IQueueTask while (true) { await TryProcessTaskAsync(); - await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken); + await Task.Delay(TimeSpan.FromSeconds(10), stoppingToken); } } } \ No newline at end of file diff --git a/InServiceQue/Services/QueueTypeRegistry.cs b/InServiceQue/Services/QueueTypeRegistry.cs index 9e4b5d7..80a48ee 100644 --- a/InServiceQue/Services/QueueTypeRegistry.cs +++ b/InServiceQue/Services/QueueTypeRegistry.cs @@ -14,6 +14,7 @@ public class QueueTypeRegistry: ITypeRegistry public IQueueHandler GetService(IServiceScope scope, string taskType) { var classType = _typeRegistry[taskType]; - return (IQueueHandler)scope.ServiceProvider.GetService(classType); + var service = scope.ServiceProvider.GetService(classType); + return (IQueueHandler)service; } } \ No newline at end of file