// Copyright (c) The Geekeey Authors // SPDX-License-Identifier: EUPL-1.2 using System.Collections; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; namespace Geekeey.Request.Dispatcher.Tests; internal sealed class SearchHandlerInAssemblyTests { [Test] public async Task I_can_search_handlers_in_an_assembly() { var assembly = Roslyn.Compile(options => options.AddFromEmbeddedSource("SearchTopLevelHandler.cs")); var services = new ServiceCollection(); services.AddRequestDispatcher(builder => builder .SearchHandlerInAssembly(assembly)); await using var provider = services.BuildServiceProvider(); var options = provider.GetRequiredService>().Value; var requestType = assembly.GetType("Sample.Ping", throwOnError: true)!; var handlerType = assembly.GetType("Sample.PingHandler", throwOnError: true)!; var handlerInterface = typeof(IScalarRequestHandler<,>).MakeGenericType(requestType, typeof(string)); var handlers = GetRequestHandlers(options, handlerInterface, provider).ToArray(); using var scope = Assert.Multiple(); await Assert.That(handlers).Count().IsEqualTo(1); await Assert.That(handlers.Single()!.GetType()).IsEqualTo(handlerType); } [Test] public async Task I_can_search_handlers_in_an_assembly_with_a_lifetime() { var assembly = Roslyn.Compile(options => options.AddFromEmbeddedSource("SearchTopLevelHandler.cs")); var services = new ServiceCollection(); services.AddRequestDispatcher(builder => builder .SearchHandlerInAssembly(assembly, ServiceLifetime.Singleton)); var handlerType = assembly.GetType("Sample.PingHandler", throwOnError: true)!; var descriptor = services.SingleOrDefault(service => service.ServiceType == handlerType); using var scope = Assert.Multiple(); await Assert.That(descriptor).IsNotNull(); await Assert.That(descriptor!.Lifetime).IsEqualTo(ServiceLifetime.Singleton); } [Test] public async Task I_can_get_an_exception_when_nested_handlers_are_present() { var assembly = Roslyn.Compile(options => options.AddFromEmbeddedSource("SearchNestedHandler.cs")); var services = new ServiceCollection(); var builder = services.AddRequestDispatcher(); await Assert.That(() => builder.SearchHandlerInAssembly(assembly)) .Throws().And.HasMessageContaining("Sample.Container+PingHandler"); } private static IEnumerable GetRequestHandlers(RequestDispatcherOptions options, Type handlerInterface, IServiceProvider provider) { return ((IEnumerable)typeof(RequestDispatcherOptions) .GetMethod(nameof(RequestDispatcherOptions.GetRequestHandlers))! .MakeGenericMethod(handlerInterface) .Invoke(options, [provider])!) .Cast(); } }