fix: registration
This commit is contained in:
@@ -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<ITypeRegistry>(_typeRegistry);
|
||||
_hostedServiceRegistrator = new HostedServiceRegistrator();
|
||||
}
|
||||
|
||||
public void AddQueue<T, THandler>()
|
||||
where T : IQueueTask
|
||||
where THandler : IQueueHandler<T>
|
||||
{
|
||||
_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<InServiceQueBuilder> buildAction)
|
||||
|
||||
{
|
||||
var builder = new InServiceQueBuilder(services);
|
||||
buildAction(builder);
|
||||
}
|
||||
|
||||
public static IServiceCollection RegisterInternals(this IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<ITypeRegistry, QueueTypeRegistry>();
|
||||
services.AddTransient<ITaskRepository, TaskRepositoryInMemory>();
|
||||
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<T>
|
||||
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<T>
|
||||
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<ITypeRegistry>();
|
||||
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;
|
||||
|
||||
|
||||
@@ -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<THostedService>(IServiceCollection services)
|
||||
where THostedService : class, IHostedService =>
|
||||
services.AddHostedService<THostedService>();
|
||||
|
||||
@@ -4,11 +4,12 @@ using InServiceQue.Sample;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
builder.Services.RegisterInternals();
|
||||
builder.Services.RegisterQueues();
|
||||
builder.Services.AddInServiceQue(builder =>
|
||||
{
|
||||
builder.AddQueue<SendMessageTask, SendMessageHandler>();
|
||||
});
|
||||
var app = builder.Build();
|
||||
|
||||
|
||||
|
||||
app.MapGet("/", (string msg) => app.Services.GetService<ITaskRepository>().Insert(new QueueTask(new SendMessageTask(new SendMessagePayload(){To = "John", From = "Garry", Message = msg}))));
|
||||
|
||||
app.Run();
|
||||
@@ -20,12 +20,12 @@ public class SendMessageTask: IQueueTask
|
||||
{
|
||||
_payload = payload;
|
||||
}
|
||||
|
||||
|
||||
public string GetTypeString()
|
||||
{
|
||||
return nameof(SendMessageTask);
|
||||
}
|
||||
|
||||
|
||||
public string GetPayloadString()
|
||||
{
|
||||
return JsonSerializer.Serialize<SendMessagePayload>(_payload);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user