implement message subscribing and worker
This commit is contained in:
19
dotnet/AipsWorker/AipsWorker.csproj
Normal file
19
dotnet/AipsWorker/AipsWorker.csproj
Normal file
@@ -0,0 +1,19 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\AipsCore\AipsCore.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="DotNetEnv" Version="3.1.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="10.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
21
dotnet/AipsWorker/Program.cs
Normal file
21
dotnet/AipsWorker/Program.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using AipsCore.Infrastructure.DI;
|
||||
using AipsWorker;
|
||||
using AipsWorker.Utilities;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
LoadingDotEnv.TryLoad();
|
||||
|
||||
var builder = Host.CreateDefaultBuilder(args);
|
||||
|
||||
builder.ConfigureServices((context, services) =>
|
||||
{
|
||||
services.AddAips(context.Configuration);
|
||||
services.AddAipsMessageHandlers();
|
||||
|
||||
services.AddHostedService<WorkerService>();
|
||||
});
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
await app.RunAsync();
|
||||
24
dotnet/AipsWorker/Utilities/LoadingDotEnv.cs
Normal file
24
dotnet/AipsWorker/Utilities/LoadingDotEnv.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using DotNetEnv;
|
||||
|
||||
namespace AipsWorker.Utilities;
|
||||
|
||||
public static class LoadingDotEnv
|
||||
{
|
||||
public static bool TryLoad()
|
||||
{
|
||||
string? dir = Directory.GetCurrentDirectory();
|
||||
|
||||
while (dir != null && !File.Exists(Path.Combine(dir, ".env")))
|
||||
{
|
||||
dir = Directory.GetParent(dir)?.FullName;
|
||||
}
|
||||
|
||||
if (dir != null)
|
||||
{
|
||||
Env.Load(Path.Combine(dir, ".env"));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
48
dotnet/AipsWorker/Utilities/SubscribeMethodUtility.cs
Normal file
48
dotnet/AipsWorker/Utilities/SubscribeMethodUtility.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using System.Reflection;
|
||||
using AipsCore.Application.Abstract.MessageBroking;
|
||||
|
||||
namespace AipsWorker.Utilities;
|
||||
|
||||
public class SubscribeMethodUtility
|
||||
{
|
||||
private readonly IMessageSubscriber _subscriber;
|
||||
|
||||
public SubscribeMethodUtility(IMessageSubscriber subscriber)
|
||||
{
|
||||
_subscriber = subscriber;
|
||||
}
|
||||
|
||||
public async Task SubscribeToMessageTypeAsync(
|
||||
Type messageType,
|
||||
object targetInstance,
|
||||
MethodInfo handlerMethod)
|
||||
{
|
||||
var subscribeMethod = GetGenericSubscribeMethod(messageType);
|
||||
var handlerDelegate = CreateHandlerDelegate(messageType, targetInstance, handlerMethod);
|
||||
|
||||
var task = (Task)subscribeMethod.Invoke(
|
||||
_subscriber,
|
||||
new object[] { handlerDelegate })!;
|
||||
|
||||
await task;
|
||||
}
|
||||
|
||||
private MethodInfo GetGenericSubscribeMethod(Type messageType)
|
||||
{
|
||||
var method = typeof(IMessageSubscriber)
|
||||
.GetMethod(nameof(IMessageSubscriber.SubscribeAsync))!;
|
||||
|
||||
return method.MakeGenericMethod(messageType);
|
||||
}
|
||||
|
||||
private Delegate CreateHandlerDelegate(
|
||||
Type messageType,
|
||||
object targetInstance,
|
||||
MethodInfo handlerMethod)
|
||||
{
|
||||
var delegateType = typeof(Func<,,>)
|
||||
.MakeGenericType(messageType, typeof(CancellationToken), typeof(Task));
|
||||
|
||||
return Delegate.CreateDelegate(delegateType, targetInstance, handlerMethod);
|
||||
}
|
||||
}
|
||||
61
dotnet/AipsWorker/WorkerService.cs
Normal file
61
dotnet/AipsWorker/WorkerService.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using System.Reflection;
|
||||
using AipsCore.Application.Abstract;
|
||||
using AipsCore.Application.Abstract.MessageBroking;
|
||||
using AipsCore.Application.Common.Message.TestMessage;
|
||||
using AipsWorker.Utilities;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
namespace AipsWorker;
|
||||
|
||||
public class WorkerService : BackgroundService
|
||||
{
|
||||
private readonly IDispatcher _dispatcher;
|
||||
private readonly SubscribeMethodUtility _subscribeMethodUtility;
|
||||
|
||||
public WorkerService(IMessageSubscriber subscriber, IDispatcher dispatcher)
|
||||
{
|
||||
_dispatcher = dispatcher;
|
||||
_subscribeMethodUtility = new SubscribeMethodUtility(subscriber);
|
||||
}
|
||||
|
||||
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
|
||||
var messageTypes = GetAllMessageTypes();
|
||||
|
||||
foreach (var messageType in messageTypes)
|
||||
{
|
||||
var handleMethod = GetMessageHandleMethod(messageType);
|
||||
|
||||
await _subscribeMethodUtility.SubscribeToMessageTypeAsync(messageType, this, handleMethod);
|
||||
}
|
||||
}
|
||||
|
||||
private IReadOnlyCollection<Type> GetAllMessageTypes()
|
||||
{
|
||||
var messageInterface = typeof(IMessage);
|
||||
var assembly = messageInterface.Assembly;
|
||||
|
||||
return assembly
|
||||
.GetTypes()
|
||||
.Where(t =>
|
||||
!t.IsAbstract &&
|
||||
!t.IsInterface &&
|
||||
messageInterface.IsAssignableFrom(t))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private async Task HandleMessage<T>(T message, CancellationToken ct) where T : IMessage
|
||||
{
|
||||
await _dispatcher.Execute(message, ct);
|
||||
}
|
||||
|
||||
private MethodInfo GetMessageHandleMethod(Type messageType)
|
||||
{
|
||||
return GetType()
|
||||
.GetMethod(nameof(HandleMessage),
|
||||
BindingFlags.Instance | BindingFlags.NonPublic)!
|
||||
.MakeGenericMethod(messageType);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user