| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263 |
- using System.Reflection;
- namespace RunnersMeet.Server;
- public class RequestHandlerModule : IAppConfigurationModule
- {
- public void ConfigureServices(IServiceCollection services, IConfigurationRoot config)
- {
- services.AddScoped<IRequestRouter, RequestRouter>();
- Register(services, new List<HandlerMatcher>
- {
- // More specific first, then fall back to more general
- new HandlerMatcher(typeof(IRequestHandler<,,>)),
- new HandlerMatcher(typeof(IRequestHandler<,>)),
- });
- }
- public void ConfigureApplication(WebApplication app)
- {
- }
- private void Register(IServiceCollection services, IList<HandlerMatcher> matchers)
- {
- foreach (var candidate in Assembly.GetExecutingAssembly().GetTypes().Where(t => t.IsClass))
- {
- var matcher = matchers.FirstOrDefault(m => m.IsMatch(candidate));
- if (matcher != null)
- {
- foreach (var handlerInterface in matcher.GetHandlerInterfaces(candidate))
- {
- services.AddScoped(handlerInterface, candidate);
- }
- }
- }
- }
- private sealed class HandlerMatcher
- {
- private readonly Type _genericInterfaceType;
- public HandlerMatcher(Type genericInterfaceType)
- {
- _genericInterfaceType = genericInterfaceType;
- }
- public bool IsMatch(Type t) => t.GetInterfaces().Any(i => ImplementsExactly(i, _genericInterfaceType));
- public IEnumerable<Type> GetHandlerInterfaces(Type t) => t.GetInterfaces().Where(i => ImplementsExactly(i, _genericInterfaceType));
- private static bool ImplementsExactly(Type candidate, Type genericInterface)
- {
- if (!candidate.IsGenericType)
- {
- return false;
- }
- var genericTypeDefinition = candidate.GetGenericTypeDefinition();
- return /*genericTypeDefinition.GenericTypeArguments.Length == genericInterface.GenericTypeArguments.Length
- &&*/ genericTypeDefinition == genericInterface;
- }
- }
- }
|