using Microsoft.Extensions.DependencyInjection; using System.Linq.Expressions; using System.Reflection; namespace Finch.Communication; internal class MessageSubscription : IMessageSubscription where TMessage : class, IMessage where TMessageHandler : IMessageHandler { public bool CanDeliver() { return typeof(TMessage).GetTypeInfo().IsAssignableFrom(typeof(T)); } public async Task Deliver(IServiceProvider serviceProvider, object message) { if (message == null) { throw new ArgumentNullException(nameof(message)); } if (!(message is TMessage)) { throw new ArgumentException($"{ nameof(message) } must be of type '{typeof(TMessage).FullName}'"); } var handlers = serviceProvider.GetServices(); foreach (var handler in handlers) { await handler.Handle((TMessage)message); } } } internal class InlineMessageSubscription : IMessageSubscription where TMessage : class, IMessage { private Expression> _handler; public InlineMessageSubscription(Expression> handler) { _handler = handler; } public bool CanDeliver() { return typeof(TMessage).GetTypeInfo().IsAssignableFrom(typeof(T)); } public async Task Deliver(IServiceProvider serviceProvider, object message) { if (message == null) { throw new ArgumentNullException(nameof(message)); } if (!(message is TMessage)) { throw new ArgumentException($"{nameof(message)} must be of type '{typeof(TMessage).FullName}'"); } await _handler.Compile()((TMessage)message); } } public interface IMessageSubscription { bool CanDeliver(); Task Deliver(IServiceProvider serviceProvider, object message); }