public async ValueTask DispatchAsync <TContext>(TContext context) where TContext : BaseContext { if (context == null) { throw new ArgumentNullException(nameof(context)); } await foreach (var handler in GetHandlersAsync()) { try { await handler.HandleAsync(context); } catch (Exception exception) when(_logger.IsEnabled(LogLevel.Debug)) { _logger.LogDebug(exception, SR.GetResourceString(SR.ID7132), handler.GetType().FullName, typeof(TContext).FullName); throw; } if (_logger.IsEnabled(LogLevel.Debug)) { _logger.LogDebug(SR.GetResourceString(SR.ID7133), typeof(TContext).FullName, handler.GetType().FullName); } switch (context) { case BaseRequestContext notification when notification.IsRequestHandled: if (_logger.IsEnabled(LogLevel.Debug)) { _logger.LogDebug(SR.GetResourceString(SR.ID7134), typeof(TContext).FullName, handler.GetType().FullName); } return; case BaseRequestContext notification when notification.IsRequestSkipped: if (_logger.IsEnabled(LogLevel.Debug)) { _logger.LogDebug(SR.GetResourceString(SR.ID7135), typeof(TContext).FullName, handler.GetType().FullName); } return; case BaseValidatingContext notification when notification.IsRejected: if (_logger.IsEnabled(LogLevel.Debug)) { _logger.LogDebug(SR.GetResourceString(SR.ID7136), typeof(TContext).FullName, handler.GetType().FullName); } return; default: continue; } } async IAsyncEnumerable <IOpenIddictServerHandler <TContext> > GetHandlersAsync() { // Note: the descriptors collection is sorted during options initialization for performance reasons. var descriptors = _options.CurrentValue.Handlers; if (descriptors.Count == 0) { yield break; } for (var index = 0; index < descriptors.Count; index++) { var descriptor = descriptors[index]; if (descriptor.ContextType != typeof(TContext) || !await IsActiveAsync(descriptor)) { continue; } var handler = descriptor.ServiceDescriptor.ImplementationInstance != null ? descriptor.ServiceDescriptor.ImplementationInstance as IOpenIddictServerHandler <TContext> : _provider.GetService(descriptor.ServiceDescriptor.ServiceType) as IOpenIddictServerHandler <TContext>; if (handler == null) { throw new InvalidOperationException(SR.FormatID1097(descriptor.ServiceDescriptor.ServiceType)); } yield return(handler); } } async ValueTask <bool> IsActiveAsync(OpenIddictServerHandlerDescriptor descriptor) { for (var index = 0; index < descriptor.FilterTypes.Length; index++) { if (!(_provider.GetService(descriptor.FilterTypes[index]) is IOpenIddictServerHandlerFilter <TContext> filter)) { throw new InvalidOperationException(SR.FormatID1098(descriptor.FilterTypes[index])); } if (!await filter.IsActiveAsync(context)) { return(false); } } return(true); } }