using System.Collections.Concurrent; using System.Reflection; using HermesSocketLibrary.Socket.Data; using Microsoft.Extensions.DependencyInjection; using Serilog; namespace HermesSocketLibrary.Requests { public abstract class RequestManager { private readonly IDictionary _requests; private readonly IServiceProvider _serviceProvider; private readonly ILogger _logger; public RequestManager(IServiceProvider serviceProvider, ILogger logger) { _serviceProvider = serviceProvider; _logger = logger; _requests = new ConcurrentDictionary(); LoadRequests(); } protected abstract string AssemblyName { get; } private void LoadRequests() { Type basetype = typeof(IRequest); var types = Assembly.Load(AssemblyName).GetTypes().Where(t => t.IsClass && !t.IsAbstract && basetype.IsAssignableFrom(t)); foreach (var type in types) { _logger.Debug($"Loading IRequest for '{type.Name}'."); var request = _serviceProvider.GetRequiredKeyedService(type.Name); _requests.Add(request.Name, request); } } public async Task Grant(string sender, RequestMessage? message) { if (message == null || message.Type == null) return new RequestResult(false, null); if (!_requests.TryGetValue(message.Type, out IRequest? request) || request == null) { _logger.Warning($"Did not find request type '{message.Type}'."); return new RequestResult(false, null); } try { return await request.Grant(sender, message.Data); } catch (Exception e) { _logger.Error(e, $"Failed to grant a request of type '{message.Type}'."); } return new RequestResult(false, null); } } }